我需要限制我的损失,以便预测总是积极的。 所以我有:
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)
我也为了简单而删除了第二个约束
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
答案 0 :(得分:1)
如果我正确理解您的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()