2017-02-17 49 views
0

我需要约束我的损失,以便预测总是正面的。 所以我有:scipy最小化不等式约束函数

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) 

还我删除了简单

第二约束

EDIT2: 我改变了我的问题如下:约束为w * X必须大于1,并且也改变了目标,所有的底片。我也改变了ARGS,所以它现在运行:

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以上

EDIT3: 我才意识到,我的预测的总和 - 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

回答

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的分量例如,如果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()