PostgreSQL:在预矢量化数据库上执行余弦相似性搜索

PostgreSQL:在预矢量化数据库上执行余弦相似性搜索,sql,django,postgresql,search,cosine-similarity,Sql,Django,Postgresql,Search,Cosine Similarity,我正试图在预矢量化的数据库表(如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

我正试图在预矢量化的数据库表(如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)
其中,向量化的属性
将包含从
原始数据生成的512维向量


例如,用户输入字符串“什么是苹果?”:

  • 输入转换为512维向量
    A
  • A
    在数据库(或非数据库)上的所有对象
    x
    上迭代
  • 在每次迭代中,计算
    A
    x之间的标准化点积(余弦相似性)。矢量化
    (请参阅)
  • 选择具有最高相似性的
    x
    对象(具有
    A
    的最高标准化内积),并打印出
    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中无法对向量执行余弦相似性。要做到这一点,您需要使用向量数据库,如or。AquilaDB支持将JSON文档与向量一起存储,我发现这非常适合您的情况。因为,您可以将交叉引用AquilaDB中索引的任何向量的元数据添加到PostgreSQL数据库中。他们的网站上有一些不错的教程。

    这对我来说很有效——请注意,它需要预规范化向量,这是一个很好的默认值:

    CREATE OR REPLACE FUNCTION dot_product_norm_d(a double precision[], b double precision[])
    RETURNS double precision AS
    $$
    SELECT sum(result)
    FROM (SELECT (tuple.val1 * tuple.val2) AS result
          FROM (SELECT UNNEST($1) AS val1,
                       UNNEST($2) AS val2,
                       generate_subscripts($1, 1) AS ix) tuple
          ORDER BY ix) inn;
    $$ LANGUAGE SQL IMMUTABLE STRICT;
    

    这里有一个相关问题的答案非常有用:

    您找到解决方案了吗?我也有同样的问题。