2016-12-14 16 views
0

行列を乗算するときに残余平方和を最小にするベクトルを見つけようとしています。関数を最小化する最適ベクトルを見つける

私はscipyの最適化パッケージ(最小化機能を持っています)を知っています。しかし、私のコードには特別な制約があります。 wの全エントリの合計(以下の関数を参照)は1に等しくなければならず、wのエントリは0より小さくなることはできません。私のためにこれを行うパッケージはありますか?そうでない場合はどうすればいいですか?

はワットを最小化しようとすると:

def w_rss(w,x0,x1): 
    predictions = np.dot(x0,w) 
    errors = x1 - predictions 
    rss = np.dot(errors.transpose(),errors).item(0) 

    return rss 

X0 = np.array([[3,4,5,3], 
       [1,2,2,4], 
       [6,5,3,7], 
       [1,0,5,2]]) 

X1 = np.array([[4], 
       [2], 
       [4], 
       [2]]) 

W = np.array([[.0], 
       [.5], 
       [.5], 
       [.0]]) 

print w_rss(W,X0,X1) 

今のところ、これはワットの可能な値をループでの私の最高の試みであるが、それが正常に動作していません。

def get_w(x0,x1): 

J = x0.shape[1] 
W0 = np.matrix([[1.0/J]*J]).transpose() 
rss0 = w_rss(W0,x0,x1) 
loop = range(J) 
for i in loop: 
    W1 = W0 
    rss1 = rss0 
    while rss0 == rss1: 
     den = len(loop)-1 
     W1[i][0] += 0.01 
     for j in loop: 
      if i == j: 
       continue 
      W1[j][0] -= 0.01/den 
      if W1[j][0] <= 0: 
       loop.remove(j) 
     rss1 = w_rss(W1,x0,x1) 
     if rss1 < rss0: 
      #print W1 
      W0 = W1 
      rss0 = rss1 
     print '--' 
     print rss0 
     print W0 

return W0,rss0 
+0

次のことが可能です:要素の和が1

あるとき、それはここでは、コードが0だされるように制約関数は、np.sum(w) - 1を返します。任意のQP(二次計画法)ソルバーを使用してください。 –

+0

私はこれをscipy.optimizeで試しました:cons =({'type': 'eq'、 'fun':ラムダx:1 - 合計(x)}){{NEW LINE}} bnds = tuple((0,1 )= {SLSQP}、bounds = bnds、constraints = cons)を最小化する(W内のxに対して){{NEW LINE}}最小化(w_rss、W1、args =(V、X0、X1)解決策は間違っていた。 –

+0

これは汎用のNLPソルバです。それは正しく設定された問題で動作するはずですが、実際のQPソルバーを使用することをお勧めします。 –

答えて

2

scipyのSLSQPコードでこれを行うことができます。 scipy.optimize.minimizemethod='SLSQPを使用するか、関数fmin_slsqpを直接使用することができます。以下では、fmin_slsqpを使用しています。

scipyのダウンロードソルバは、一般的にそう一致するように、私は1次元配列であることがWX1を変更するだろう、と私は今、(目的関数を記述します、目的関数に一次元配列を渡しますw_rss1)は、1-d引数wを期待しています。

wのすべての要素が0と1の間になければならないという条件は、bounds引数を使用して指定され、合計が1でなければならないという条件はf_eqcons引数を使用して指定されます。

import numpy as np 
from scipy.optimize import fmin_slsqp 


def w_rss1(w, x0, x1): 
    predictions = np.dot(x0, w) 
    errors = x1 - predictions 
    rss = (errors**2).sum() 
    return rss 


def sum1constraint(w, x0, x1): 
    return np.sum(w) - 1 


X0 = np.array([[3,4,5,3], 
       [1,2,2,4], 
       [6,5,3,7], 
       [1,0,5,2]]) 

X1 = np.array([4, 2, 4, 2]) 

W = np.array([.0, .5, .5, .0]) 

result = fmin_slsqp(w_rss1, W, f_eqcons=sum1constraint, bounds=[(0.0, 1.0)]*len(W), 
        args=(X0, X1), disp=False, full_output=True) 
Wopt, fW, its, imode, smode = result 

if imode != 0: 
    print("Optimization failed: " + smode) 
else: 
    print(Wopt) 

私はこれを実行すると、出力は

[ 0.05172414 0.55172414 0.39655172 0.  ] 
関連する問題