Python scipy最小化不等式约束函数

Python scipy最小化不等式约束函数,python,optimization,scipy,constraints,Python,Optimization,Scipy,Constraints,我需要控制我的损失,这样预测总是积极的。 因此,我: 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.do

我需要控制我的损失,这样预测总是积极的。 因此,我:

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函数中使用constraints参数,因此我认为它应该是这样的:

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       ] 


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

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

现在,表达式
|y-w*x | ^2
w
中是二次的,因此它有一个定义良好的全局最小值(
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的其他分量(例如,如果
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()

为了使这个问题变得更有用(即,我发现它与答案一起有用),可能需要删除编辑部分,并以更简洁的版本重新编写这个问题——否则,尽管这是一个好问题,但还是有点难以理解
def con(w,x,y,alpha):
    return np.minimum(w*x - 1, 0).sum()