下面是我几周前分配给我的一个类的python代码,我一直无法成功调试.问题在于如何使用FFT找到总损失随机变量的风险值(即p%分位数).我们给出了一个清晰的数学过程,通过这个过程我们可以得到总损失随机变量的离散化CDF的估计.然而,我的结果非常糟糕,我犯了一些错误,即使在调试了几个小时的代码之后,我也找不到这些错误.

给出了总损失随机变量S,其中S=sum(X_i for i in range(N))r=5, beta=.2呈负二项分布,X_itheta=1呈指数分布.这个参数化的概率母函数是P(z)=[1-\beta(z-1)]^{-r}.

我们被要求估计S人的分布情况

  1. Select 网格宽度h和整数n,使得r=2^n是离散X的元素数,
  2. 离散化X,并计算在宽度为h的等间距间隔内的概率,
  3. 将FFT应用于离散化的X
  4. 将PGF N应用于傅里叶变换X的元素,
  5. 将逆FFT应用于该向量.

得到的向量应该是S的每个这样的区间的概率质量的近似值.我从以前的方法中知道,95%的VaR应该是~4,99.9%的VaR应该是~10.但我的代码返回的结果毫无意义.一般来说,我的ECDF达到的指数>0.95太晚了,即使经过几个小时的调试,我也没有找到哪里出了问题.

我也在math stackexchange上问过这个问题,因为这个问题在很大程度上是关于编程和数学的交叉点,我现在不知道这个问题是在实现方面,还是我应用的数学思想是错误的.

import numpy as np
from scipy.stats import expon
from scipy.fft import fft, ifft

r, beta, theta = 5, .2, 1
var_levels = [.95, .999]


def discretize_X(h: float, m: int):
    X = expon(scale=theta)
    f_X = [X.cdf(h / 2),
           *[X.cdf(j * h + h / 2) - X.cdf(j * h - h / 2) for j in range(1, m - 1)],
           X.sf((m - 1) * h - h / 2)]
    return f_X


# Probability generating function of N ~ NB(r, beta)
def PGF(z: [float, complex]):
    return (1 - beta * (z - 1)) ** (-r)


h = 1e-2
n = 10
r = 2 ** n

VaRs, TVaRs = [], []

# discretize X with (r-1) cells of width h and one final cell with the survival function at h*(r-1)
f_X = discretize_X(h, r)
phi_vec = fft(f_X)
f_tilde_vec_fft = np.array([PGF(phi) for phi in phi_vec])
f_S = np.real(ifft(f_tilde_vec_fft))
ecdf_S = np.cumsum(f_S)  # calc cumsum to get ECDF

for p in var_levels:
    var_idx = np.where(ecdf_S >= p)[0][0]  # get lowest index where ecdf_S >= p
    print("p =", p, "\nVaR idx:", var_idx)
    var = h * var_idx  # VaR should be this index times the cell width
    print("VaR:", var)
    tvar = 1 / (1 - p) * np.sum(f_S[var_idx:] * np.array([i * h for i in range(var_idx, r)]))  # TVaR should be each cell's probability times the value inside that cell

    VaRs.append(var)
    TVaRs.append(tvar)

return VaRs, TVaRs

推荐答案

不确定数学,但在代码段中,变量r被重写,当计算f_tilde_vec_fft时,函数PGF使用5,而不是预期的r,而是1024.修复--将超参数定义中的名称r更改为r_nb:

r_nb, beta, theta = 5, .2, 1

在函数PGF中:

return (1 - beta * (z - 1)) ** (-r_nb)

运行后,其他参数保持不变(如hn等),对于VaRs,我得到[4.05, 9.06]

Python相关问答推荐

调试回归无法解决我的问题

除了Python之外,可以替代bare?

Flask主机持续 bootstrap 本地IP| Python

如何在Python中按组应用简单的线性回归?

删除pandas rame时间序列列中未更改的值

如何使用PyTest根据self 模拟具有副作用的属性

从今天起的future 12个月内使用Python迭代

从DataFrame.apply创建DataFrame

对整个 pyramid 进行分组与对 pyramid 列子集进行分组

沿着数组中的轴计算真实条目

如何在solve()之后获得症状上的等式的值

如果条件不满足,我如何获得掩码的第一个索引并获得None?

将9个3x3矩阵按特定顺序排列成9x9矩阵

使用Python更新字典中的值

合并帧,但不按合并键排序

为什么numpy. vectorize调用vectorized函数的次数比vector中的元素要多?

Pandas:计算中间时间条目的总时间增量

为什么在FastAPI中创建与数据库的连接时需要使用生成器?

当单元测试失败时,是否有一个惯例会抛出许多类似的错误消息?

如何删除重复的文字翻拍?