python 如何在Redis向量相似性搜索中优先考虑维度?

4nkexdtk  于 2023-06-04  发布在  Python
关注(0)|答案(2)|浏览(171)

我目前正在使用Redis作为一个矢量数据库,并且能够得到一个三维的相似性搜索(维度是纬度,经度和时间戳)。相似性搜索正在工作,但我想在进行搜索时以不同的方式权衡某些维度。也就是说,我希望相似性搜索在进行搜索时优先考虑时间戳维度。
我该怎么办?Redis似乎没有任何内置功能可以做到这一点。
我使用下面的代码将每一组纬度、经度和时间坐标转换为可以放入向量数据库的字节。注意vector_dict存储所有lat、long和timestamp的集合:

p = client.pipeline(transaction=False)
for index in data:
        # create hash key
        key = keys[index]

        # create hash values
        item_metadata = data[index] # copy all metadata
        item_key_vector = np.array(vector_dict[index]).astype(np.float32).tobytes() # convert vector to bytes
        p.hset(key, mapping=item_metadata) # add item to redis using hash key and metadata

然后,我使用HNSW索引进行相似性搜索:

def create_hnsw_index(redis_conn, vector_field_name, number_of_vectors, vector_dimensions=3, distance_metric='L2', M=100, EF=100):
    redis_conn.ft().create_index([
        VectorField(vector_field_name, "HNSW", {"TYPE": "FLOAT32", "DIM": vector_dimensions, "DISTANCE_METRIC": distance_metric, "INITIAL_CAP": number_of_vectors, "M": M, "EF_CONSTRUCTION": EF})
    ])

我和其他人谈过,他们说这是一个处理向量归一化的数学问题。我不确定如何开始与此虽然在代码中,并希望一些指导。

w6mmgewl

w6mmgewl1#

您可以对向量重新加权,以使某些维度比其他维度更长。你使用的是L2距离度量。它使用标准的勾股定理来计算距离:

dist = sqrt((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2)

假设您将查询和数据库中的每个Y值乘以10。这也将使Y值之间的差乘以10倍。
新的距离函数实际上将是这样的:

dist = sqrt((x1-x2)**2 + (10*(y1-y2))**2 + (z1-z2)**2)

dist = sqrt((x1-x2)**2 + 100*(y1-y2)**2 + (z1-z2)**2)

...这使得Y维度比其他维度重要100倍。
因此,如果你想让位置2中的维度更重要,你可以这样做:

item_key_vector = np.array(vector_dict[index])
item_key_vector[2] *= 10
item_key_vector_bytes = item_key_vector.astype(np.float32).tobytes()

乘以的具体数量取决于您希望时间戳有多重要。请记住,您需要将查询向量乘以相同的数量。

0sgqnhkj

0sgqnhkj2#

这不是对您问题的回答,但请注意,如果您正在寻找向量相似性,使用{纬度,经度}作为向量元素不是一个好方法。
例如{-179.99,0}和{+179.99,0}或{0,89.99}和{180,89.99}这样的点对之间的距离很小,但向量不会相似。
最好将每个{纬度,经度}对转换为笛卡尔{x,y,z}。请看精彩的答案here
至于你的问题,Nick奥德尔的回答是解决此类问题的标准方法:扩展数据。

相关问题