scipy 如何使用fsolve改进函数?

yvt65v4c  于 2023-03-30  发布在  其他
关注(0)|答案(1)|浏览(131)

我想在每次迭代中逐个使用fsolve。假设我有DataFrame如下所示:
| PD下降|PD TTC|
| --------------|--------------|
| 0.12 |0.008|
| 0.15 |0.016|
| 0.24 |0.056|
| 0.56 |零点一六|
| 1.00 |一千|
下面是我尝试的代码:

result = []
for i in range(len(df) - 1):
  def R(x):
    ZDownturn = norm.ppf(df['PD Downturn'])[i] #Exclude 'Default' class
    ZShift = np.sqrt(
        x / (1 - x)
    ) * norm.ppf(0.999)
    ZPortion = np.sqrt(
        1 / (1 - x)
    ) * norm.ppf(df['PD TTC'])[i] #Exclude 'Default' class
    target = ZShift + ZPortion
    error =  np.abs(ZDownturn - target)
    return error

  # Initial guess
  x0 = [0.01]
  
  # Solver
  Rho = fsolve(R, x0)
  result.append(Rho[0])

我想根据一些计算逻辑找到x变量,但我需要一个接一个地做。所以,我在每次迭代中创建新函数。结果如下:

[0.19153452995548875,
 0.15906256238706026,
 0.08759684851688349,
 0.1348702069117432]

这是工作,但我正在寻找另一种方式,也许更pythonic的方式来编写代码。
谢谢大家。

dw1jzc5e

dw1jzc5e1#

你可能正在寻找目标函数的向量化版本。这正是numpy的闪光点:

import numpy as np
from scipy.optimize import fsolve
from scipy.stats import norm

pd_downturn = np.array([0.12, 0.15, 0.24, 0.56])
pd_ttc = np.array([0.008, 0.016, 0.056, 0.160])
#pd_downturn = df['PD Downturn'].values[:-1]
#pd_ttc = df['PD TTC'].values[:-1]

def R(x):
    ZDownturn = norm.ppf(pd_downturn)
    ZShift = np.sqrt(x / (1 - x)) * norm.ppf(0.999)
    ZPortion = np.sqrt(1 / (1 - x)) * norm.ppf(pd_ttc)
    target = ZShift + ZPortion
    error = (ZDownturn - target)**2
    return error

# Initial guess
x0 = 0.01*np.ones(pd_downturn.size)
  
# Solver
result = fsolve(R, x0)

注意你应该尽可能避免使用np.abs来求根或优化问题,而只是平方差。绝对值函数在其参数为零的点是不可微的,因此你会违反大多数算法的数学假设。

相关问题