我喜欢开发一个查询系统,根据从数据中提取的二进制签名,找到与给定项目最相似的项目。因为我有运行时约束,所以我会探索最有效的方法。我试图使用scipy距离,但它太慢了。你知道任何其他有用的库或技巧,以更快的方式。
对于存在和示例场景,
我有一个长度为68的二进制值的查询向量,我有一个矩阵大小为3000Kx68的数据集。我喜欢通过使用汉明距离在此矩阵中找到最相似的项目给出查询。
感谢任何评论
答案 0 :(得分:1)
好问题,我喜欢Alex和Piotr的答案。我的第一次天真尝试也导致解决时间大约800ms(在我的系统上)。我的第二次尝试,使用numpy的(un)packbits
,导致速度提高了4倍。
import numpy as np
LENGTH = 68
K = 1024
DATASIZE = 3000 * K
DATA = np.random.randint(0, 2, (DATASIZE, LENGTH)).astype(np.bool)
def RandomVect():
return np.random.randint(0, 2, (LENGTH)).astype(np.bool)
def HammingDist(vec1, vec2):
return np.sum(np.logical_xor(vec1, vec2))
def SmallestHamming(vec):
XorData = np.logical_xor(DATA, vec[np.newaxis, :])
Lengths = np.sum(XorData, axis=1)
return DATA[np.argmin(Lengths)] # returns first smallest
def main():
v1 = RandomVect()
v2 = SmallestHamming(v1)
print(HammingDist(v1, v2))
# oke, lets try make it faster... (using numpy.(un)packbits)
DATA2 = np.packbits(DATA, axis=1)
NBYTES = DATA2.shape[-1]
BYTE2ONES = np.zeros((256), dtype=np.uint8)
for i in range(0,256):
BYTE2ONES[i] = np.sum(np.unpackbits(np.uint8(i)))
def RandomVect2():
return np.packbits(RandomVect())
def HammingDist2(vec1, vec2):
v1 = np.unpackbits(vec1)
v2 = np.unpackbits(vec2)
return np.sum(np.logical_xor(v1, v2))
def SmallestHamming2(vec):
XorData = DATA2 ^ vec[np.newaxis, :]
Lengths = np.sum(BYTE2ONES[XorData], axis=1)
return DATA2[np.argmin(Lengths)] # returns first smallest
def main2():
v1 = RandomVect2()
v2 = SmallestHamming2(v1)
print(HammingDist2(v1, v2))
答案 1 :(得分:0)
如果速度明显快于此,我会感到惊讶:将数据放入pandas DataFrame(M
),每个向量按列,将目标向量放入pandas系列({{1} }),
x
然后执行以下操作
import numpy as np
import pandas as pd
rows = 68
columns=3000
M = pd.DataFrame(np.random.rand(rows,columns)>0.5)
x = pd.Series(np.random.rand(rows)>0.5)
编辑:实际上,我很惊讶这是一种更快的方式
%timeit M.apply(lambda y: x==y).astype(int).sum().idxmax()
1 loop, best of 3: 746 ms per loop
答案 2 :(得分:0)
使用SciPy中的cdist
:
from scipy.spatial.distance import cdist
Y = cdist(XA, XB, 'hamming')
计算归一化汉明距离,或两个不同意的n向量u和v之间的向量元素的比例。为了节省内存,矩阵X可以是boolean类型
参考:http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html