Python scipy.optimize.minimize中的元素约束

Python scipy.optimize.minimize中的元素约束,python,numpy,machine-learning,scipy,mathematical-optimization,Python,Numpy,Machine Learning,Scipy,Mathematical Optimization,我正在使用scipy.optimize.minimize的COBYLA方法来查找分类分布的参数矩阵。我需要强制每个参数都大于零,并且参数矩阵的行和是一列1 我不清楚如何在scipy.minimize中实现这一点,因为约束是针对非负性而不是真实性进行检查的。如果我只是将数组作为约束传递,那么最小化会引发一个异常 有人知道如何实现这些约束吗?第一个约束x>0可以非常简单地表达: {'type':'ineq', 'fun': lambda x: x} 第二个约束是相等约束,COBYLA本机不支持该约

我正在使用
scipy.optimize.minimize
的COBYLA方法来查找分类分布的参数矩阵。我需要强制每个参数都大于零,并且参数矩阵的行和是一列1

我不清楚如何在
scipy.minimize
中实现这一点,因为约束是针对非负性而不是真实性进行检查的。如果我只是将数组作为约束传递,那么最小化会引发一个异常


有人知道如何实现这些约束吗?

第一个约束
x>0
可以非常简单地表达:

{'type':'ineq', 'fun': lambda x: x}
第二个约束是相等约束,COBYLA本机不支持该约束。但是,您可以将其表示为两个独立的不等式约束:

{'type':'ineq', 'fun': lambda x: np.sum(x, 0) - 1}  # row sum >= 1
{'type':'ineq', 'fun': lambda x: 1 - np.sum(x, 0)}  # row sum <= 1
{'type':'ineq','fun':lambda x:np.sum(x,0)-1}#行和>=1

{'type':'ineq','fun':lambda x:1-np.sum(x,0)}#row sum您需要执行
np.sum(x,1)==1
的等式约束和
x>=0
的不等式约束

但是,COBYLA方法只能处理不等式约束,如的文档中所述(请参阅解释
约束
参数的部分)。相反,您可以使用序列最小二乘编程(SLSQP),它支持这两种类型的约束。
minimize
函数应根据指定的约束自动为您选择正确的解算器

您需要的约束可以这样实现:

def ineq_constraint(x):
    """constrain all elements of x to be >= 0"""
    return x

def eq_constraint(x):
    """constrain the sum of all rows to be equal to 1"""
    return np.sum(x, 1) - 1


constraints = [{'type': 'ineq', 'fun': ineq_constraint},
               {'type': 'eq', 'fun': eq_constraint}]

result = minimize(objective_function, x0, constraints=constraints)

我实验室的一位成员提出了一个技巧,其中最后一列参数固定为一,参数由输出的softmax给出。这消除了对我提到的约束的需要。不过,我认为这个问题的答案对其他人还是有用的。这个建议不是很清楚,你能提供更多的细节吗?这很有效,谢谢!我有单独的不等式约束,所以我将继续使用COBYLA。我发现上限/下限技巧非常有效。只约束最小的元素而不是所有元素是非常聪明的。我必须记住这一点。它很聪明,但实际上会使模型更难求解,因为它引入了不连续性。也就是说,总的来说,这不是一个好主意。像min和max这样的函数将像瘟疫一样被避免。@ErwinKalvelagen你说得对-我将删除mins。我把它们放在那里的原因是。我已经很久没有使用那个解算器了,我没有意识到现在支持向量值约束。