2017-04-03 90 views
1

我正在努力寫漢明距離。
作爲輸入我確實有兩個矩陣M1和M2,一個是40x20,第二個50x20;它們包含真/假。我需要計算每行之間的距離,因此M2 [0],M1 [0]與M2 [1] ... M1 [39]與M2 [49]之間的距離爲M1 [0]。產生40x50結果矩陣。我的第一次嘗試當然循環如下:漢明距離蟒蛇改進

for x_i in range(X.shape[0]): 
     for x_train_j in range(X_train.shape[0]): 
      distance_results[x_i, x_train_j] = sum(np.logical_xor(x_array[x_i, :], x_train_array[x_train_j, :])) 

這是正確的,但是,它對我的​​數據來說太慢了。我對乘以M1.dot(M2.T),這給矩陣的正確的形狀的一些想法,並在一個步驟並總結,但乘以總結XOR當需要這樣:
1 * 1 = 1(需要0 - 壞)
1 * 0 = 0(需要1 - 壞)
0 * 1 = 0(需要1-差)
0 * 0 = 0(需要0--還可以)
你有什麼想法我怎麼能得到想要的結果?我想我錯過了一些數學正確和快速的做法。 在此先感謝。

+0

你可以嘗試使用numba加快執行。 Numba提供「及時」編譯來加速執行。更多信息在這裏:http://numba.pydata.org/ 給出的例子(sum2d)可以很容易地適應您的需要。 – ma3oun

+0

我的講師給出了一些關於使用標量乘法的建議,但是我仍然無法完成它 –

回答

1

M1.dot(M2.T)對於布爾邏輯可以認爲是AND。對於二進制邏輯A xor B相當於(A and not B) or (not A and B)等於是一兩件事你可以做 -

M1.dot(M2.T): 
1 * 1 = 1 
1 * 0 = 0 
0 * 1 = 0 
0 * 0 = 0 

(not M1).dot(M2.T): 
0 * 1 = 0 
0 * 0 = 0 
1 * 1 = 1 
1 * 0 = 0 

M1.dot(not M2.T): 
1 * 0 = 0 
1 * 1 = 1 
0 * 0 = 0 
0 * 1 = 0 

(not M1).dot(M2.T) or M1.dot(not M2.T): 
0 * 1 || 1 * 0 = 0 
0 * 0 || 1 * 1 = 1 
1 * 1 || 0 * 0 = 1 
1 * 0 || 0 * 1 = 0 

要編寫它你需要小心使得總量計算小數點前投的邏輯了。如果你點上2個邏輯陣列,你不會得到你想要的結果。我只使用-1作爲我的非運營商(True - 1 = 0, False - 1 = -1)。此外,這裏的'或'是真正的總和,因爲你正在考慮多個布爾。最後,你最終將你的距離放在負面,很容易用絕對解決。

_A = [[ True, True, False], 
     [ True, False, True]] 

_B = [[ True, False, False], 
     [ False, False, False], 
     [ True, True, True ]] 

預期輸出: [1,2,1], [1,2,1]

A = numpy(_A, dtype=bool) 
B = numpy(_B, dtype=bool) 

numpy.absolute(numpy.dot(A,B.T-1) + numpy.dot(A-1, B.T)) 

>>>array([[1, 2, 1], 
      [1, 2, 1]]) 
+1

它計算漢明距離。所以我不明白它缺少什麼 – gbtimmon

+0

謝謝你,請試試看。看起來不錯。我正在考慮它,但錯過了如何做出負面(-1技巧)。假我;;) –