Python 找到使函数最小化的最优向量

Python 找到使函数最小化的最优向量,python,vector,scipy,quadratic-programming,quadprog,Python,Vector,Scipy,Quadratic Programming,Quadprog,我试图找到一个向量,当乘以一个矩阵时,使剩余平方和最小化 我知道scipy的优化包(它有一个最小化功能)。然而,我的代码还有一个额外的约束。w的所有条目之和(参见下面的函数)必须等于1,并且w的任何条目都不能小于0是否有为我提供此服务的软件包?如果没有,我如何才能做到这一点 尝试最小化w: def w_rss(w,x0,x1): predictions = np.dot(x0,w) errors = x1 - predictions rss = np.dot(errors

我试图找到一个向量,当乘以一个矩阵时,使剩余平方和最小化

我知道scipy的优化包(它有一个最小化功能)。然而,我的代码还有一个额外的约束。w的所有条目之和(参见下面的函数)必须等于1,并且w的任何条目都不能小于0是否有为我提供此服务的软件包?如果没有,我如何才能做到这一点

尝试最小化w:

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)
到目前为止,这是我在循环可能的w值方面的最佳尝试,但它不能正常工作

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
def get_w(x0,x1):
J=x0.形状[1]
W0=np.矩阵([[1.0/J]*J]).转置()
rss0=w_rss(W0,x0,x1)
回路=范围(J)
对于循环中的i:
W1=W0
rss1=rss0
当rss0==rss1时:
den=透镜(环路)-1
W1[i][0]+=0.01
对于循环中的j:
如果i==j:
持续
W1[j][0]-=0.01/den

如果W1[j][0]则scipy中的SLSQP代码可以执行此操作。您可以与
method='SLSQP
一起使用,也可以直接使用该函数。在下面,我使用
fmin_slsqp

scipy解算器通常将一维数组传递给目标函数,因此为了保持一致,我将
W
X1
更改为一维数组,并将目标函数(现在称为
W_rss1
)写入一维参数
W

使用
bounds
参数指定
w
中所有元素必须介于0和1之间的条件,使用
f_eqcons
参数指定总和必须为1的条件。约束函数返回
np.sum(w)-1
,因此当元素之和为1时,它为0

代码如下:

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.        ]

scipy中的SLSQP代码可以做到这一点。您可以与
method='SLSQP
一起使用,也可以直接使用该函数。在下面,我使用
fmin_slsqp

scipy解算器通常将一维数组传递给目标函数,因此为了保持一致,我将
W
X1
更改为一维数组,并将目标函数(现在称为
W_rss1
)写入一维参数
W

使用
bounds
参数指定
w
中所有元素必须介于0和1之间的条件,使用
f_eqcons
参数指定总和必须为1的条件。约束函数返回
np.sum(w)-1
,因此当元素之和为1时,它为0

代码如下:

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.        ]

您可以使用任何QP(二次规划)解算器来解决这个问题。我在scipy.optimize:cons=({'type':'eq','fun':lambda x:1-sum(x)}{{NEW LINE}}bnds=tuple((0,1)for x in W){{NEW LINE}}最小化(W_rss,W1,args=(V,X0,X1),method SLSQP',bounds=bnds constraints=cons)。解决方案不正确。这是一个通用NLP解算器。它应该能处理正确的设置问题,但我建议使用真正的QP解算器。你可以使用任何QP(二次规划)解算器来解决这个问题。我在scipy.optimize:cons=({type':'eq','fun':lambda x:1-sum(x){{newline}}bnds tuple((0,1)for x in W){newline}最小化(W_rss,W1,args=(V,X0,X1),method='SLSQP',bounds=bnds,constraints=cons)。解决方案不正确。这是一个通用NLP解算器。它应该与一个正确的设置问题,但我建议使用一个真正的QP解算器。