找到最适合目标向量的向量线性组合
Find linear combination of vectors that is the best fit for a target vector
我试图在多个预测中找到权重,以给出尽可能接近已知目标(例如,均方误差)的结果。
这是一个简化示例,显示了跨四个数据点的三种不同类型的预测:
target = [1.0, 1.02, 1.01, 1.04] # all approx 1.0
forecasts = [
[0.9, 0.91, 0.92, 0.91], # all approx 0.9
[1.1, 1.11, 1.13, 1.11], # all approx 1.1
[1.21, 1.23, 1.21, 1.23] # all approx 1.2
]
其中一项预测始终约为 0.9,一项始终约为 1.1,一项始终约为 1.2。
我想要一种自动方法来为三个预测找到大约 [0.5, 0.5, 0.0]
的权重,因为平均前两个预测并忽略第三个非常接近目标。理想情况下,权重将被限制为非负且总和为 1。
我认为我需要使用某种形式的线性规划或二次规划来做到这一点。我已经安装了 Python quadprog library,但我不确定如何将此问题转换为此类求解器所需的形式。谁能指出我正确的方向?
如果我对你的理解是正确的,你想对一些优化问题建模并解决它。如果您对一般情况感兴趣(没有任何限制),您的问题似乎非常接近常规最小二乘误差问题(例如,您可以用 scikit-learn
解决)。
我建议使用 cvxpy 库来建模优化问题。这是对凸优化问题建模的便捷方式,您可以选择要在后台运行的求解器。
通过添加您提到的约束来扩展 cvxpy least square example:
# Import packages.
import cvxpy as cp
import numpy as np
# Generate data.
m = 20
n = 15
np.random.seed(1)
A = np.random.randn(m, n)
b = np.random.randn(m)
# Define and solve the CVXPY problem.
x = cp.Variable(n)
cost = cp.sum_squares(A @ x - b)
prob = cp.Problem(cp.Minimize(cost), [x>=0, cp.sum(x)==1])
prob.solve()
# Print result.
print("\nThe optimal value is", prob.value)
print("The optimal x is")
print(x.value)
print("The norm of the residual is ", cp.norm(A @ x - b, p=2).value)
在此示例中,A
(矩阵)是所有向量的矩阵,x
(变量)是权重,b
是已知目标。
编辑:
您的数据示例:
forecasts = np.array([
[0.9, 0.91, 0.92, 0.91],
[1.1, 1.11, 1.13, 1.11],
[1.21, 1.23, 1.21, 1.23]
])
target = np.array([1.0, 1.02, 1.01, 1.04])
x = cp.Variable(forecasts.shape[0])
cost = cp.sum_squares(forecasts.T @ x - target)
prob = cp.Problem(cp.Minimize(cost), [x >= 0, cp.sum(x) == 1])
prob.solve()
print("\nThe optimal value is", prob.value)
print("The optimal x is")
print(x.value)
输出:
The optimal value is 0.0005306233766233817
The optimal x is
[ 6.52207792e-01 -1.45736370e-24 3.47792208e-01]
结果大约是 [0.65, 0, 0.34]
,这与您提到的 [0.5, 0.5, 0.0]
不同,但这取决于您如何定义问题。这是最小二乘误差的解决方案。
我们可以把这个问题看成一个最小二乘,确实等价于二次规划。如果我理解正确的话,你要找的权重向量是一个凸组合,所以最小二乘形式的问题是:
minimize || [w0 w1 w2] * forecasts - target ||^2
s.t. w0 >= 0, w1 >= 0, w2 >= 0
w0 + w1 + w2 == 1
qpsolvers 包中有一个开箱即用的最小二乘函数:
import numpy as np
from qpsolvers import solve_ls
target = np.array(target)
forecasts = np.array(forecasts)
w = solve_ls(forecasts.T, target, G=-np.eye(3), h=np.zeros(3), A=np.array([1, 1., 1]), b=np.array([1.]))
您可以在documentation中查看矩阵G、h、A和b对应于上述问题。使用 quadprog 作为后端求解器,我在我的机器上得到以下解决方案:
In [6]: w
Out[6]: array([6.52207792e-01, 9.94041282e-15, 3.47792208e-01])
In [7]: np.dot(w, forecasts)
Out[7]: array([1.00781558, 1.02129351, 1.02085974, 1.02129351])
这与 Roim 的回答中的解决方案相同。 (CVXPY 确实是一个很好的开始方式!)
我试图在多个预测中找到权重,以给出尽可能接近已知目标(例如,均方误差)的结果。
这是一个简化示例,显示了跨四个数据点的三种不同类型的预测:
target = [1.0, 1.02, 1.01, 1.04] # all approx 1.0
forecasts = [
[0.9, 0.91, 0.92, 0.91], # all approx 0.9
[1.1, 1.11, 1.13, 1.11], # all approx 1.1
[1.21, 1.23, 1.21, 1.23] # all approx 1.2
]
其中一项预测始终约为 0.9,一项始终约为 1.1,一项始终约为 1.2。
我想要一种自动方法来为三个预测找到大约 [0.5, 0.5, 0.0]
的权重,因为平均前两个预测并忽略第三个非常接近目标。理想情况下,权重将被限制为非负且总和为 1。
我认为我需要使用某种形式的线性规划或二次规划来做到这一点。我已经安装了 Python quadprog library,但我不确定如何将此问题转换为此类求解器所需的形式。谁能指出我正确的方向?
如果我对你的理解是正确的,你想对一些优化问题建模并解决它。如果您对一般情况感兴趣(没有任何限制),您的问题似乎非常接近常规最小二乘误差问题(例如,您可以用 scikit-learn
解决)。
我建议使用 cvxpy 库来建模优化问题。这是对凸优化问题建模的便捷方式,您可以选择要在后台运行的求解器。
通过添加您提到的约束来扩展 cvxpy least square example:
# Import packages.
import cvxpy as cp
import numpy as np
# Generate data.
m = 20
n = 15
np.random.seed(1)
A = np.random.randn(m, n)
b = np.random.randn(m)
# Define and solve the CVXPY problem.
x = cp.Variable(n)
cost = cp.sum_squares(A @ x - b)
prob = cp.Problem(cp.Minimize(cost), [x>=0, cp.sum(x)==1])
prob.solve()
# Print result.
print("\nThe optimal value is", prob.value)
print("The optimal x is")
print(x.value)
print("The norm of the residual is ", cp.norm(A @ x - b, p=2).value)
在此示例中,A
(矩阵)是所有向量的矩阵,x
(变量)是权重,b
是已知目标。
编辑: 您的数据示例:
forecasts = np.array([
[0.9, 0.91, 0.92, 0.91],
[1.1, 1.11, 1.13, 1.11],
[1.21, 1.23, 1.21, 1.23]
])
target = np.array([1.0, 1.02, 1.01, 1.04])
x = cp.Variable(forecasts.shape[0])
cost = cp.sum_squares(forecasts.T @ x - target)
prob = cp.Problem(cp.Minimize(cost), [x >= 0, cp.sum(x) == 1])
prob.solve()
print("\nThe optimal value is", prob.value)
print("The optimal x is")
print(x.value)
输出:
The optimal value is 0.0005306233766233817
The optimal x is
[ 6.52207792e-01 -1.45736370e-24 3.47792208e-01]
结果大约是 [0.65, 0, 0.34]
,这与您提到的 [0.5, 0.5, 0.0]
不同,但这取决于您如何定义问题。这是最小二乘误差的解决方案。
我们可以把这个问题看成一个最小二乘,确实等价于二次规划。如果我理解正确的话,你要找的权重向量是一个凸组合,所以最小二乘形式的问题是:
minimize || [w0 w1 w2] * forecasts - target ||^2
s.t. w0 >= 0, w1 >= 0, w2 >= 0
w0 + w1 + w2 == 1
qpsolvers 包中有一个开箱即用的最小二乘函数:
import numpy as np
from qpsolvers import solve_ls
target = np.array(target)
forecasts = np.array(forecasts)
w = solve_ls(forecasts.T, target, G=-np.eye(3), h=np.zeros(3), A=np.array([1, 1., 1]), b=np.array([1.]))
您可以在documentation中查看矩阵G、h、A和b对应于上述问题。使用 quadprog 作为后端求解器,我在我的机器上得到以下解决方案:
In [6]: w
Out[6]: array([6.52207792e-01, 9.94041282e-15, 3.47792208e-01])
In [7]: np.dot(w, forecasts)
Out[7]: array([1.00781558, 1.02129351, 1.02085974, 1.02129351])
这与 Roim 的回答中的解决方案相同。 (CVXPY 确实是一个很好的开始方式!)