scipy-生成具有相关性的随机变量

2024-04-28 22:21:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正努力在Python中实现一个基本的Monte Carlo模拟器,用于我正在尝试做的一些项目管理风险建模(基本上是Crystal Ball/@risk,但在Python中)。

我有一组n随机变量(所有scipy.stats实例)。我知道我可以使用rv.rvs(size=k)从每个n变量生成k独立的观察结果。

我想通过指定一个n x n半正定相关矩阵来引入变量之间的相关性。

有没有一个干净的方法来做到这一点在西皮?

我尝试过的

This answerthis answer似乎表明“copulas”是一个答案,但我在scipy中没有看到任何对它们的引用。

This link似乎实现了我正在寻找的功能,但我不确定scipy是否已经实现了这个功能。我也希望它适用于非正态变量。

似乎Iman, Conover paper是标准方法。


Tags: 方法answer功能statsscipy模拟器this建模
2条回答

如果您只想通过高斯Copula(*)进行相关,那么可以使用numpy和scipy在几步内计算出相关。

  • 创建具有期望协方差的多变量随机变量,numpy.random.multivariate_normal,并创建(nobs by k_variables)数组

  • 应用scipy.stats.norm.cdf将正态随机变量转换为均匀随机变量,对于每个列/变量获得均匀的边际分布

  • 应用dist.ppf将均匀边距转换为所需分布,其中dist可以是scipy.stats

    中的分布之一

(*)高斯copula只是一个选择,当我们对尾部行为感兴趣时,它不是最好的,但是它是最容易使用的 例如http://archive.wired.com/techbiz/it/magazine/17-03/wp_quant?currentPage=all

两个参考文献

https://stats.stackexchange.com/questions/37424/how-to-simulate-from-a-gaussian-copula

http://www.mathworks.com/products/demos/statistics/copulademo.html

(我以前在python中可能已经这样做了,但现在没有任何脚本或函数。)

看起来你想要的是基于拒绝的抽样方法,比如Metropolis-Hastings算法。Scipy可以使用其scipy.optimize.basinhopping函数实现此类方法。

基于拒绝的抽样方法允许您从任何给定的概率分布中抽取样本。我们的想法是从另一个“建议”pdf中随机抽取样本,该pdf很容易从中抽取样本(例如均匀分布或高斯分布),然后使用随机测试来确定是否应该“接受”来自建议分布的该样本作为所需分布的样本。

剩下的技巧是:

  1. 求出N维联合概率密度函数的形式,它沿着每个维有你想要的形式的边缘,但是有你想要的相关矩阵。对于高斯分布,这很容易实现,在高斯分布中,所需的相关矩阵和平均向量就是定义分布所需的全部。如果你的边缘有一个简单的表达式,你可能会发现这个pdf有一些简单但乏味的代数。This这篇论文引用了其他一些人的观点,我敢肯定还有更多的人。

  2. basinhopping制定一个函数,以最小化它,使它被接受的“最小”数量等于您定义的这个pdf的样本。

鉴于(1)的结果,(2)应该是直截了当的。

相关问题 更多 >