import typing
import numpy as np
import scipy.stats
def run_gaussian_copula_simulation_and_get_samples(
ppfs: typing.List[typing.Callable[[np.ndarray], np.ndarray]],
cov_matrix: np.ndarray,
num_samples: int,
) -> np.ndarray:
num_dims = len(ppfs)
ran = np.random.multivariate_normal(np.zeros(num_dims), cov_matrix, (num_samples,), check_valid="raise")
U = scipy.stats.norm.cdf(ran)
return np.array([ppfs[i](U[:, i]) for i in range(num_dims)]).T
f1 = run_gaussian_copula_simulation_and_get_samples(
[lambda x: scipy.stats.norm.ppf(x, loc=100, scale=15), scipy.stats.norm.ppf],
[[1, 0], [0, 1]],
6
)
f2 = run_gaussian_copula_simulation_and_get_samples(
[lambda x: scipy.stats.norm.ppf(x, loc=100, scale=15), scipy.stats.norm.ppf],
[[1, 1], [1, 1]],
6
)
np.set_printoptions(suppress=True)
print(f1)
print(f2)
关于这个函数的一些说明。
np.random.multivariate_normal
为我们做了很多繁重的工作,特别要注意的是我们不需要分解相关矩阵。
ppfs
被传递为一个函数列表,每个函数都有一个输入和一个返回值。
在我的特定用例中,我需要生成多元
t-分布随机变量(除了正态分布),
请参考此答案以了解如何实现:
https://dev59.com/957ha4cB1Zd3GeqPnbQo#41967819。
此外,我使用
scipy.stats.t.cdf
进行反变换部分。
在我的特定用例中,所需的分布是代表预期财务损失的经验分布。
然后,最终数据点必须相加以获得所有单个但相关的财务事件的总财务损失。
因此,在我的代码库中,
np.array(...).T
实际上被
sum(...)
替换。