我从scipy中的优化函数开始。
我试图通过复制Find optimal vector that minimizes function解决方案来创建代码
我有一个数组,其中包含多个列中的序列。我需要将每个列乘以一个权重,这样这些列的最后一行的总和乘以权重就得到一个给定的数字(约束)。
这个序列的和乘以权重得到一个新的序列,我在这里提取了最大下降,我想最小化这个mdd。
我尽我所能地写了我的代码(2个月的Python和3个小时的scipy),但无法解决用于解决问题的函数上的错误信息。
这里是我的代码和任何帮助将不胜感激:
import numpy as np
from scipy.optimize import fmin_slsqp
# based on: https://stackoverflow.com/questions/41145643/find-optimal-vector-that-minimizes-function
# the number of columns (and so of weights) can vary; it should be generic, regardless the number of columns
def mdd(serie): # finding the max-draw-down of a series (put aside not to create add'l problems)
min = np.nanargmax(np.fmax.accumulate(serie) - serie)
max = np.nanargmax((serie)[:min])
return serie[np.nanargmax((serie)[:min])] - serie[min] # max-draw-down
# defining the input data
# mat is an array of 5 columns containing series of independent data
mat = np.array([[1, 0, 0, 1, 1],[2, 0, 5, 3, 4],[3, 2, 4, 3, 7],[4, 1, 3, 3.1, -6],[5, 0, 2, 5, -7],[6, -1, 4, 1, -8]]).astype('float32')
w = np.ndarray(shape=(5)).astype('float32') # 1D vector for the weights to be used for the columns multiplication
w0 = np.array([1/5, 1/5, 1/5, 1/5, 1/5]).astype('float32') # initial weights (all similar as a starting point)
fixed_value = 4.32 # as a result of constraint nb 1
# testing the operations that are going to be used in the minimization
series = np.sum(mat * w0, axis=1)
# objective:
# minimize the mdd of the series by modifying the weights (w)
def test(w, mat):
series = np.sum(mat * w, axis=1)
return mdd(series)
# constraints:
def cons1(last, w, fixed_value): # fixed_value = 4.32
# the sum of the weigths multiplied by the last value of each column must be equal to this fixed_value
return np.sum(mat[-1, :] * w) - fixed_value
def cons2(w): # the sum of the weights must be equal to 1
return np.sum(w) - 1
# solution:
# looking for the optimal set of weights (w) values that minimize the mdd with the two contraints and bounds being respected
# all w values must be between 0 and 1
result = fmin_slsqp(test, w0, f_eqcons=[cons1, cons2], bounds=[(0.0, 1.0)]*len(w), args=(mat, fixed_value, w0), full_output=True)
weights, fW, its, imode, smode = result
print(weights)
1条答案
按热度按时间hc2pp10m1#
你说的也不算太离谱,最大的问题在于mdd函数:如果没有draw-down,你的函数会吐出一个空列表作为中间结果,这样就不能再科普argmax函数了。
此外,必须确保所有相关函数(成本函数和约束)的参数列表相同。
还有一点:您可以使用@-运算符使矩阵向量乘法更加精简。