繁体   English   中英

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

[英]Issue with Python scipy optimize minimize fmin_slsqp solver

我从 scipy 的优化 function 开始。

我试图通过复制最小化 function 解决方案的 Find 最佳向量来创建我的代码

我有一个包含列中的系列的数组。 我需要将它们中的每一个乘以权重,以便这些列的最后一行的总和乘以权重得到给定的数字(约束)。

该系列的总和乘以权重给出了一个新系列,我在其中提取了最大下降,并且我想最小化这个 mdd。

我尽可能地编写了我的代码(2 个月的 Python 和 3 小时的 scipy)并且无法解决用于解决问题的 function 上的错误消息。

这是我的代码,任何帮助将不胜感激:

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)

你离目标并不远。 最大的问题在于 mdd function:如果没有回撤,您的 function 会吐出一个空列表作为中间结果,然后就无法再处理 argmax ZC1C425268E68384F145A。

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

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

# 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)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM