Python scipy优化最小化fmin_slsqp求解程序的问题

pdtvr36n  于 2022-11-10  发布在  Python
关注(0)|答案(1)|浏览(198)

我从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)
hc2pp10m

hc2pp10m1#

你说的也不算太离谱,最大的问题在于mdd函数:如果没有draw-down,你的函数会吐出一个空列表作为中间结果,这样就不能再科普argmax函数了。

def mdd(serie):  # finding the max-draw-down of a series (put aside not to create add'l problems)
    i = np.argmax(np.maximum.accumulate(serie) - serie) # end of the period
    start = serie[:i]
    # check if there is dd at all
    if not start.any():
        return 0
    j = np.argmax(start) # start of period
    return serie[j] - serie[i]  # max-draw-down

此外,必须确保所有相关函数(成本函数和约束)的参数列表相同。


# objective:

# minimize the mdd of the series by modifying the weights (w)

def test(w, mat,fixed_value):
    series = mat @ w
    return mdd(series)

# constraints:

def cons1(w, mat, 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 mat[-1, :] @ w - fixed_value

def cons2(w, mat, fixed_value):  # 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, eqcons=[cons1, cons2], bounds=[(0.0, 1.0)]*len(w), args=(mat,fixed_value), full_output=True)

还有一点:您可以使用@-运算符使矩阵向量乘法更加精简。

相关问题