当我运行这个时,我真的不明白 SLSQP 在做什么,目标函数的分母始终是 nan (如回调中所示)。当我将 x0 插入分母时,我得到一个实际数字,所以我不明白为什么它立即在回调中出现 nan ?
from scipy.optimize import minimize
import numpy as np
n = 250
x0 = np.ones(n) / n
pred = np.random.normal(loc=0.07, scale=0.2, size=(n))
c = ((np.random.random(size = (n, n)))-0.5) *0.1
def objective(weights):
if np.sum(weights) == 0:
return 10
else:
return -np.dot(weights, pred)/(np.sqrt(np.dot(weights, np.dot(c, weights)))) # /
def custom_callback(xk):
print(np.dot(xk, pred) , (np.sqrt(np.dot(xk, np.dot(c, xk)))))
constraints = (
{'type': 'ineq', 'fun': lambda weights: np.abs(np.sum(weights)) - 0.03},
{'type': 'ineq', 'fun': lambda weights: 1.03 - np.sum(np.abs(weights))},
{'type': 'ineq', 'fun': lambda weights: np.sum(np.abs(weights))-0.97},
)
bounds = tuple((-0.02, 0.02) for asset in range(len(x0)))
result = minimize(objective, x0, method='SLSQP', bounds=bounds, constraints=constraints, options={'disp': 2, 'maxiter' : 100}, callback=custom_callback)
插入 x0 的分母:
np.sqrt(np.dot(x0, np.dot(c, x0)))
x0
。c
通常是正定的。abs
是不可微分的,违反了 SQLSQP 的平滑假设。