我正努力在Python中实现一个基本的Monte Carlo模拟器,用于我正在尝试做的一些项目管理风险建模(基本上是Crystal Ball/@risk,但在Python中)。
我有一组n
随机变量(所有scipy.stats
实例)。我知道我可以使用rv.rvs(size=k)
从每个n
变量生成k
独立的观察结果。
我想通过指定一个n x n
半正定相关矩阵来引入变量之间的相关性。
有没有一个干净的方法来做到这一点在西皮?
我尝试过的
This answer和this answer似乎表明“copulas”是一个答案,但我在scipy中没有看到任何对它们的引用。
This link似乎实现了我正在寻找的功能,但我不确定scipy是否已经实现了这个功能。我也希望它适用于非正态变量。
似乎Iman, Conover paper是标准方法。
如果您只想通过高斯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很容易从中抽取样本(例如均匀分布或高斯分布),然后使用随机测试来确定是否应该“接受”来自建议分布的该样本作为所需分布的样本。
剩下的技巧是:
求出N维联合概率密度函数的形式,它沿着每个维有你想要的形式的边缘,但是有你想要的相关矩阵。对于高斯分布,这很容易实现,在高斯分布中,所需的相关矩阵和平均向量就是定义分布所需的全部。如果你的边缘有一个简单的表达式,你可能会发现这个pdf有一些简单但乏味的代数。This这篇论文引用了其他一些人的观点,我敢肯定还有更多的人。
为
basinhopping
制定一个函数,以最小化它,使它被接受的“最小”数量等于您定义的这个pdf的样本。鉴于(1)的结果,(2)应该是直截了当的。
相关问题 更多 >
编程相关推荐