PostgreSQL: поиск косинусного сходства по предварительно векторизованной базе данных - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь реализовать поиск сходства по косинусу в предварительно векторизованной таблице базы данных (например, сходство триграмм), имеющей объекты в этой структуре:

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.


Например, пользователь вводит строку «Что такое яблоко?»:

  1. Ввод преобразуется в 512-мерныйvector A.
  2. A повторяется по всем объектам x в базе данных (или нет).
  3. На каждой итерации нормализованное скалярное произведение (косинусное сходство) вычисляется междуA и x.vectorized (см. определение косинусного сходства ).
  4. 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?

Спасибо!

1 Ответ

0 голосов
/ 15 августа 2019

Невозможно выполнить косинусное сходство для векторов внутри PostgreSQL.Для этого вам необходимо использовать векторную базу данных, например AquilaDB или EuclidesDB .AquilaDB поддерживает хранение документов JSON вместе с векторами, что, на мой взгляд, очень подходит в вашем случае.Потому что вы можете добавить любые метаданные, которые будут ссылаться на любой вектор, проиндексированный в AquilaDB, в вашу базу данных PostgreSQL.На их вики-странице есть несколько хороших руководств .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...