我试图在预矢量化的数据库表(如trigram相似性)上实现余弦相似性搜索,该结构中有对象:
from django.contrib.postgres.fields import ArrayField
from django.db import models
class Information(object):
vectorized = ArrayField(models.FloatField(default=0.0)) # will contain 512-dimensional vector of floats
original_data = models.TextField(blank=True)
original_data_length = models.IntegerField(default=0)
其中属性
vectorized
将包含由original_data
生成的512维向量。例如,用户输入一个字符串“什么是苹果?”:
输入转换为512维向量
A
。A
在数据库上的所有对象上迭代(或不迭代)。在每次迭代中,标准化点积(余弦相似性)在
x
和A
之间计算(见cosine similarity definition)。选择相似度最高的对象(最高规格化内积为
x.vectorized
),并打印出x
。为此,我实现了简单的代码,它效率低下,因为它是在框架级别而不是数据库级别执行的,并且为数据库表中的所有对象分配了内存:
from core.models import Information
from numpy import dot # dot product = inner product limited for real numbers
from numpy.linalg import norm
user_input = user_input # let this be 512 dimensional vector converted from user input
most_similar = ("", 0)
for item in Information.objects.all():
similarity = dot(item, user_input)/norm(item, user_input)
if similarity > most_similar[1]:
most_similar = (item.original_data, similarity)
print(most_similar[0])
有没有办法实现上述代码的更有效的方法?
使用PostgreSQL有什么办法吗?
谢谢您!
最佳答案
在PostgreSQL中不可能对向量执行余弦相似性。为此,需要使用向量数据库,如AquilaDB或EuclidesDB。AquilaDB支持将JSON文档与向量一起存储,我发现这非常适合您的情况。因为,您可以将任何将交叉引用AquilaDB中索引的任何向量的元数据添加到PostgreSQL数据库中。他们的wiki page有一些很好的教程。
关于sql - PostgreSQL:在预先向量化的数据库上执行余弦相似度搜索,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52429918/