簡體   English   中英

使用scipy最小化帶有參數的函數

[英]Minimize a function with parameters with scipy

我想問一下如何使用scipy最小化中的優化方法來最小化一個函數(平方誤差之和)。 我嘗試過,但似乎我做得不好,因為錯誤和參數與初始值沒有變化。 這是我的代碼:

def objective(p, y):
    y = np.array([98.494500, 97.828500, 97.610000, 97.314000, 97.014500, 92.959000, 96.696222])
    p = beta0, beta1, beta2, beta3, tau1, tau2
    return  (((100 * DiscountFactor('rate',np.exp(p[0] + (p[1]+ p[2]) * (1 - np.exp(-yearfractionTenors()/p[4])) * p[4]/yearfractionTenors() - p[2] * np.exp(-yearfractionTenors()/p[4]) + p[3] * (1 - np.exp(-yearfractionTenors()/p[5])) * p[5] / yearfractionTenors() - p[3] * np.exp(-yearfractionTenors() / p[5])) -1, fecha_valoracion, maturity, composition= 'linear', basis= 'act/360').result) - y) ** 2).sum()
x0 = np.array([0.03, -0.03, 0, 0, 1, 1]) #Initial values of beta0, beta1, beta2, beta3, tau1 and tau2
res = optimize.minimize(objective, x0, args = y)
print(res)
output: fun: 64.30571361326217
hess_inv: array([[1, 0, 0, 0, 0, 0],
   [0, 1, 0, 0, 0, 0],
   [0, 0, 1, 0, 0, 0],
   [0, 0, 0, 1, 0, 0],
   [0, 0, 0, 0, 1, 0],
   [0, 0, 0, 0, 0, 1]])
  jac: array([0., 0., 0., 0., 0., 0.])
  message: 'Optimization terminated successfully.'
  nfev: 8
  nit: 0
  njev: 1
 status: 0
 success: True
    x: array([ 0.03, -0.03,  0.  ,  0.  ,  1.  ,  1.  ])

看來我的錯誤是我沒有很好地使用輸入值(初始值)。 我想知道是否有人可以幫助我解決這個問題。 基本上,我想知道如何通過更改初始數組中的參數來最小化函數。 也許錯誤在於目標函數。 這個問題的一個小例子:

def objective(p, y):
    y = np.array([98.494500, 97.828500, 97.610000, 97.314000, 97.014500, 92.959000, 96.696222])
    p = beta0, beta1, beta2, beta3, tau1, tau2
    return  (((100 * DiscountFactor('rate',np.exp(p[0] + (p[1]+ p[2]) * (1 - np.exp(-yearfractionTenors()/p[4])) * p[4]/yearfractionTenors() - p[2] * np.exp(-yearfractionTenors()/p[4]) + p[3] * (1 - np.exp(-yearfractionTenors()/p[5])) * p[5] / yearfractionTenors() - p[3] * np.exp(-yearfractionTenors() / p[5])) -1, fecha_valoracion, maturity, composition= 'linear', basis= 'act/360').result) - y) ** 2).sum()
x0 = np.array([0.03, -0.03, 0, 0, 1, 1]) #Initial values of beta0, beta1, beta2, beta3, tau1 and tau2
res = optimize.minimize(objective, x0, args = y)
print(res)

折扣因子函數無關緊要,但是這是您需要運行它的類:

class DiscountFactor:

def __init__(self, val_given, value, start_date, end_date, composition, basis):
    self.start_date = start_date
    self.end_date = end_date
    self.composition = composition
    self.basis = basis
    self.yf = year_fraction(start_date, end_date, basis)

    if val_given == 'rate':
        self.rate_to_df(value) 
    else:
        raise ValueError('val_given must be: rate or df' )

def rate_to_df(self, rate):
    if self.composition == 'linear':
        df = 1/( 1 + rate*self.yf)
    else:
        raise ValueError('composition must be one of the following: linear, yearly, biannual, continuous')
    self.result = df
    return self.result

作為Askold Ilvento,您正在函數范圍內重新定義參數。 這將使優化失敗,因為函數將始終產生相同的結果。 這也是一種不好的做法,也是潛在的錯誤來源。 嘗試:

def objective(p, y):
    return  (((100 * DiscountFactor('rate',np.exp(p[0] + (p[1]+ p[2]) * (1 - np.exp(-yearfractionTenors()/p[4])) * p[4]/yearfractionTenors() - p[2] * np.exp(-yearfractionTenors()/p[4]) + p[3] * (1 - np.exp(-yearfractionTenors()/p[5])) * p[5] / yearfractionTenors() - p[3] * np.exp(-yearfractionTenors() / p[5])) -1, fecha_valoracion, maturity, composition= 'linear', basis= 'act/360').result) - y) ** 2).sum()

x0 = np.array([0.03, -0.03, 0, 0, 1, 1]) #Initial values of beta0, beta1, beta2, beta3, tau1 and tau2
y = np.array([98.494500, 97.828500, 97.610000, 97.314000, 97.014500, 92.959000, 96.696222]) 
beta0, beta1, beta2, beta3, tau1, tau2 = optimize.minimize(objective, x0, args = y)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM