2016-10-02 39 views
0

我目前在梯度下降實現問題上掙扎,更多的是在數學方面。我有一個輸入值的矩陣,例如 - [[1,1,0,2],[2,3,5,1],[2,1,8,0]]。我想計算權重,將對輸出向量的誤差最小化,最小化的函數是標準線性模型,所以我的假設是最小化 - >np.dot(input,weights)-y。問題是 - 權向量的值應該加上特定的數字,比如說2.也輸出向量的歸一化,如np.dot(input,weights)/sum(np.dot(input,weights)) - 然後將這個結果與期望的輸出向量進行比較。我應該如何在python/numpy中定義這個任務?人類調諧過程的一般優化 - python中的實現

示例:期望

1)輸入矩陣 [[4,0,2,0,2,0],[2,0,0,2,2,0],[2,0,0,2,2,0],[4,0,2,0,0,0],[0,0,2,0,0,2],[0,4,0,0,0,2],[0,2,0,0,0,2],[0,2,2,0,0,0],[0,0,2,0,0,2],[4,0,2,0,0,0]]

2)輸出[12.94275893,8.07054252,9.281123898,10.53654162,8.698251382,14.67643103,7.158870124,10.26752354,8.324615155,10.0433418]

3)變換以這樣的方式,np.dot輸入矢量的權重(輸入,權重)/總和(np.dot(輸入,權重))沒問題 [11,21,18,0,20,14] - 總和固定爲84

4)最終產出,合理偏差泰德2)[15.15,7.83,7.83,10.10,8.08,14.14,8.84,9.85,8.08,10.10]

+0

我不清楚你在問什麼。 '''問題是 - 權重向量的值應該加上具體的數字,比如說2'''這是什麼意思?爲什麼正常化很重要?通常你正在適應一個規範器,然後準備好轉換新的數據。另外:這是爲了研究/學習目的嗎?因爲有很多好的軟件爲你做這件事。 – sascha

+0

我的意思是我的權重是固定在他們的總和 - 這些值的總和應該是2. – tretyacv

+0

這聽起來像一個** np-hard **問題,然後這是不可能解決一般!它也不再是一個凸優化問題。當然,你可以得到一個近似的解決方案,並添加一個懲罰項,這個懲罰項對於這個值的偏差是有效的。但好吧..仍然是非凸的,我認爲(這將意味着:非常難以優化)。 **編輯:**也許我的感覺錯了。如果使用罰款期限,它應該是凸的。 – sascha

回答

-1

對於示例數據的比例,這裏是解決方案:

import numpy as np 
from scipy import optimize 

a = np.array([[1,1,0,2],[2,3,5,1],[2,1,8,0]], dtype=float) 
target = np.random.randn(3) 
target /= target.sum() 

def f(p): 
    p = np.r_[p, 2 - p.sum()] 
    res = a.dot(p) 
    res /= res.sum() 
    return res - target 

r, _ = optimize.leastsq(f, np.zeros(3)) 
print(target) 
print(np.r_[r, 2 - r.sum()]) 

輸出:

[-0.21987606 0.70869974 0.51117632] 
[ 2.15713915 7.47554671 0.38959227 -8.02227813] 

這裏是你的真實數據的代碼:

import numpy as np 
from scipy import optimize 

a = np.array([[4,0,2,0,2,0], 
       [2,0,0,2,2,0], 
       [2,0,0,2,2,0], 
       [4,0,2,0,0,0], 
       [0,0,2,0,0,2], 
       [0,4,0,0,0,2], 
       [0,2,0,0,0,2], 
       [0,2,2,0,0,0], 
       [0,0,2,0,0,2], 
       [4,0,2,0,0,0]], dtype=float) 

target = np.array([12.94275893,8.07054252,9.281123898,10.53654162,8.698251382, 
        14.67643103,7.158870124,10.26752354,8.324615155,10.0433418]) 

target /= target.sum() 

def make_vector(x): 
    return np.r_[x, 84 - x.sum()] 

def calc_target(x): 
    res = a.dot(make_vector(x)) 
    res /= res.sum() 
    return res 

def error(x): 
    return calc_target(x) - target 

x, _ = optimize.leastsq(error, np.zeros(a.shape[1] - 1)) 
print(make_vector(x)) 
print(calc_target(x) * 100) 
print((calc_target(x) - target) * 100) 

輸出:

[ 9.40552097 20.32874298 19.8199082 13.13991088 10.00062863 
    11.30528834] 
[ 12.90025777 8.63333209 8.63333209 10.2474406 8.25642656 
    13.78390749 8.39140263 10.65003363 8.25642656 10.2474406 ] 
[-0.04250116 0.56278957 -0.64779181 -0.28910102 -0.44182483 -0.89252354 
    1.23253251 0.38251009 -0.0681886 0.2040988 ] 

看來這個問題也可以通過numpy.linalg.lstsq()來解決,但它需要將你的問題簡化爲線性方程。

+2

OP在數學方面苦苦掙扎,絕對看起來像是想學習的人。我建議爲未來的讀者添加一些解釋,畢竟Stack Overflow不是代碼編寫服務。 –

+1

感謝您的回覆!我會在較大的數據集上進行測試並通知您。正如安德拉斯提到的,我也會很感激任何理論上的見解 – tretyacv

+1

這個代碼中隱藏着一些假設/模型決定(損失+罰分與1.0個人因素共同最小化),並且提及這些將是非常好的。即使是(在我看來)numpy-aware(非guru-)用戶在看到像''np_r_'''這樣的東西時掙扎着。儘管如此:有趣的代碼。 – sascha