簡體   English   中英

找到最適合目標向量的向量線性組合

[英]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 ,但我不確定如何將這個問題轉化為求解器需要的形式。 誰能指出我正確的方向?

如果我理解正確的話,你想要 model 一些優化問題並解決它。 如果您對一般情況感興趣(沒有任何限制),您的問題似乎非常接近常規最小二乘誤差問題(例如,您可以使用scikit-learn解決)。

我建議使用cvxpy庫對優化問題進行建模。 這是解決 model 凸優化問題的便捷方法,您可以選擇要在后台運行的求解器。

通過添加您提到的約束來擴展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)

Output:

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 package 中有一個開箱即用的最小二乘法function

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

您可以查看文檔,矩陣 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 確實是一個很好的開始方式!)

暫無
暫無

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

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