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