【问题标题】:scipy minimize inequality constraint functionscipy 最小化不等式约束函数
【发布时间】:2017-07-07 06:40:42
【问题描述】:

我需要限制我的损失,以便预测总是积极的。 所以我有:

x = [1.0,0.64,0.36,0.3,0.2]
y = [1.0,0.5,0.4,-0.1,-0.2]
alpha = 0

def loss(w, x, y, alpha):
    loss = 0.0
    for y_i,x_i in zip(y,x):
        loss += ((y_i - np.dot(w,x_i)) ** 2)
    return loss + alpha * math.sqrt(np.dot(w,w))

res = minimize(loss_new_scipy, 0.0, args=(x, y, alpha))

现在我想添加约束,但我发现大多数约束 x 在边界之间,而不是 np.dot(w,x)>= 0 这样的约束是什么样子的?

编辑: 我想在 scipy.optimize.minimize 函数中使用约束参数,所以我认为它应该看起来像这样:

def con(w,x):
    loss = 0.0
    for i_x in x:
         loss += (np.dot(w, i_x))
    return loss


cons = ({'type': 'ineq', 'fun': con})
res = minimize(loss_new_scipy, 0.0, args=(x, y, alpha), constraints=cons)

为了简单起见,我还删除了第二个约束

编辑2: 我将问题更改为以下内容:约束是 w*x 必须大于 1,并且还将目标更改为所有负数。我还更改了参数,所以它现在运行:

x = np.array([1.0,0.64,0.36,0.3,0.2])
y = [-1.0,-0.5,-0.4,-0.1,-0.2]
alpha = 0

def con(w,x,y,alpha):
    print np.array(w*x)
    return np.array((w*x)-1).sum()


cons = ({'type': 'ineq', 'fun': con,'args':(x,y,alpha)})

def loss_new_scipy(w, x, y, alpha):
    loss = 0.0
    for y_i,x_i in zip(y,x):
        loss += ((y_i - np.dot(w,x_i)) ** 2)
    return loss + alpha * math.sqrt(np.dot(w,w))

res = minimize(loss_new_scipy, np.array([1.0]), args=(x, y, alpha),constraints=cons)
print res

但不幸的是,w 的结果是 2.0,这确实是正数,看起来约束有所帮助,因为它距离将函数拟合到目标还很远,但预测 w*x 并非都高于 1.0

编辑3: 我刚刚意识到我的预测之和 - 1 现在等于 0,但我希望每个预测都大于 1.0 所以 w = 2.0,

w*x = [ 2.00000001  1.28000001  0.72        0.6         0.4       ] 

(w*x) - 1 = [ 1.00000001  0.28000001 -0.28       -0.4        -0.6       ]

总和等于 0.0,但我希望所有预测 w*x 大于 1.0,因此 w*x 中的所有 5 个值至少应为 1.0

【问题讨论】:

  • 为了可能使这个问题变得更有帮助(即,我发现它与答案一起很有用)可能是删除编辑部分并以更简洁的版本重新编写 - 否则,它是尽管这是一个好问题,但有点难以理解

标签: python optimization scipy constraints


【解决方案1】:

如果我正确理解您的 EDIT2,您正试图将 |y - w*x|^2 最小化为实际参数 w 的函数(其中 xy 是向量),约束条件是 w*x 具有所有组件大于 1。

现在,表达式|y - w*x|^2w 中是二次的,因此它具有明确定义的全局最小值(w^2 前面的因子是正数)。但是,对w*x 的组件的约束有效地施加了w 的最小允许值(因为x 是固定的),在这种情况下为5。由于二次(无约束)函数|y - w*x|^2 的全局最小值适用于np.dot(y,x)/np.dot(x,x)=-0.919 附近的特定情况,因此对于w>=5,该函数单调递增,因此5 的值代表约束最小值......

要使用您的代码获得此答案,必须修复约束。在您的情况下,您将 w*x 的所有分量相加,偏移 1。然而,在这里,一个特定分量可能远大于 1,因此它对总和的贡献可能会掩盖仅略小于 1 的其他分量1(例如,如果x=[2, 0.25]w=2,然后是w*x-1=[3,-0.5],因此即使违反了约束,总和也是正数)。为了纠正这一点,可以只对w*x-1 的那些为负的分量求和,即那些违反约束的分量:

def con(w,x,y,alpha):
    return np.minimum(w*x - 1, 0).sum()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 2013-12-03
    • 2019-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多