我使用scipy.optimize.minimize
的COBYLA方法来查找分类分布的参数矩阵。我需要强加每个参数大于零的约束,并且参数矩阵的行总和是一列。scipy.optimize.minimize中的元素限制
我不清楚如何在中实现这一点,因为约束检查的是非否定性而非真实性。如果我只是传递数组作为约束,最小化会引发异常。
有谁知道如何去执行这些约束?
我使用scipy.optimize.minimize
的COBYLA方法来查找分类分布的参数矩阵。我需要强加每个参数大于零的约束,并且参数矩阵的行总和是一列。scipy.optimize.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
否则,你可以尝试SLSQP代替,这不支持等式约束。
这个作品,谢谢!我有单独的不平等约束,所以我会坚持与COBYLA。我发现上/下限技巧工作得很好。 –
只限制最小的元素而不是所有元素都非常聪明。我必须记住这一点。 – kazemakase
这很聪明,但实际上会导致模型更难解决,因为它引入了不连续性。即一般来说这不是一个好主意。像瘟疫一样避免像min和max这样的函数。 –
您需要实施np.sum(x, 1) == 1
的平等约束和x >= 0
的不等式约束。
但是,COBYLA方法只能处理不等式约束,如文档minimize
(参见解释constraints
参数的部分)中所述。相反,您可以使用支持这两种约束的Sequential Least SQuares Programming(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给出。这消除了我提到的限制的需要。不过,我认为这个问题的答案对其他人有用。 –