sql - PostgreSQL:对预矢量化数据库执行余弦相似度搜索
问题描述
我正在尝试在预矢量化的数据库表(如三元相似度)上实现余弦相似度搜索,具有以下结构的对象:
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
将包含 512 维向量,该向量是从original_data
.
例如,用户输入一个字符串“什么是苹果?”:
- 输入被转换为 512 维向量
A
。 A
迭代x
数据库上的所有对象(或不迭代)。A
在每次迭代中,计算和之间的归一化点积(余弦相似度)x.vectorized
(参见余弦相似度定义)。x
选择相似度最高的对象(与 的最高归一化内积A
)并x.original_data
打印出来。
我为此目的实现了简单的代码,它效率低下,因为它是在框架级别而不是数据库级别执行的,并且为数据库表中的所有对象分配了内存:
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 做到这一点?
谢谢!
解决方案
这一直对我有用——请注意,它需要预先标准化的向量,这无论如何都是一个很好的默认值:
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;
这里有一个相关问题的答案很有帮助:Vector (array) addition in Postgres
推荐阅读
- go - 通过分片进行 grpc 负载均衡
- visual-studio-code - vscode 中的 electron-forge --template=typescript-webpack 给出错误 Unable to resolve path to module './moduleName'
- node.js - 我应该为 Google Home 本地执行应用使用什么 URL
- zapier - Zapier 的正则表达式提取美元金额
- spring - Spring HATEOAS 和实体 DTO - ModelAssembler 的问题
- jersey - 使用球衣,我如何为错误生成 json 并为成功生成八位字节流
- javascript - 使用Javascript SVG画线时,多个
- html - HTML如何在单个文件中切换页面
- php - 如何在多while循环php中合并两个具有唯一值的数组
- intellij-idea - oracle数据库和intellij-idea如何建立连接