簡體   English   中英

scipy最小化不等式約束函數

[英]scipy minimize inequality constraint function

我需要限制自己的損失,以便預測始終是積極的。 所以我有:

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

如果我正確理解您的EDIT2,則您嘗試根據實數參數w (其中xy是向量)的函數來最小化|y - w*x|^2 ,並限制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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM