Как стать автором
Обновить

Комментарии 14

Ожидания - МЛ, эмбединги, векторные БД… реальность - Neo4j…

Я правильно понимаю, что ваш "алгоритм" сводится к косинусному расстоянию по фиксированному набору признаков?

У алгоритма есть линейная сложность o(n).

...где n - это что?

Да, все верно, алгоритм сводится к косинусному расстоянию по фиксированному набору признаков. Вообще-то сложность O(4N), так как в нем четыре независимых цикла, но в описании сложности принято константы отбрасывать.

Вообще-то сложность O(4N), так как в нем четыре независимых цикла, но в описании сложности принято константы отбрасывать.

Где N - это что?

N - это количество итераций цикла, которое зависит от количества параметров, т.е чем больше параметров, тем больше итераций и тем выше latency.

То есть у вас алгоритм с линейной сложностью от числа параметров. Вроде бы, для косинусного расстояния это тривиально. Но не суть.

Я правильно понимаю, что у вас эта сложность посчитана для одной рекомендации; иными словами, для M объектов, из которых мы выбираем рекомендации, "реальная" (наблюдаемая пользователем) сложность будет O(M*N) (потому что вам для каждого объекта надо выполнить ваш алгоритм)?

PS Еще, кстати, интересный вопрос: N - это число всех возможных параметров (т.е. всех ключевых слов в системе), или только используемых в конкретной паре?

Отвечаю на ваш первый вопрос:
Да все верно, сложность только для одного сравнения.
В моем случае, все посты имели в среднем 76 классификаторов, а у пользователя в качестве опыта их было 45
Количество постов было ~10000 и рекомендация отдавалась за 600ms, что меня полностью устраивало.

Отвечаю на ваш второй вопрос:
В сравнении участвуют только классификаторы отдельно взятого поста и пользователя

Да все верно, сложность только для одного сравнения.

Тогда правильнее говорить, что сложность - O(N*M). И это, будем честными, тривиальная сложность для косинуса.

Проблемы начинаются тогда, когда N радикально больше, чем у вас.

В сравнении участвуют только классификаторы отдельно взятого поста и пользователя

А вы уверены, что получающиеся результаты (дистанции, полученные в разных пространствах) корректно сравнивать между собой?

Алгоритм проектировался под рекомендации, если эта тема интересует можете посмотреть мою публикацию на медиуме "Easy way to build recommendation in Neo4J"

Так я про рекомендательную систему и спрашиваю.

За случайный минус прошу простить - ткнул с телефона мимо, плюсанул в карму в качестве извинений.

Для второй части вектора применим те самые действия, что и для первого, и уравновесим их, приводя их максимумы к одному общему знаменателю по следующей формуле: n/max(n).

А почему, кстати, нормализация по максимуму, а не по сумме?

Вообще, конечно, в этот момент уже надо доставать из кармана тестовый датасет, и на нем считать метрики, какой подход дает лучший результат.

Нормализация происходила по max, чтобы в топ поднимались только те категории, у которых максимальный вес.
Вот простая демонстрация

Я это сделал с помощью следующего запроса:

CREATE (:Classifier{id: 0, keyword: 'sky'})
CREATE (:Classifier{id: 1, keyword: 'ocean'})
CREATE (:Classifier{id: 2, keyword: 'nature'})
CREATE (:Classifier{id: 3, keyword: 'alp'})
CREATE (:Classifier{id: 4, keyword: 'mountain'})

MATCH (c:Classifier) WHERE rand() > 0.5
WITH apoc.coll.shuffle(COLLECT(c)) AS classifiers
UNWIND classifiers AS classifier
WITH classifier, toFloat(rand()*100) AS rnd
WITH COLLECT(classifier.id) AS ux_classifiers, COLLECT(rnd) AS ux_features, COLLECT(classifier.keyword + '(' + toInteger(rnd) + ')') AS ux_title
UNWIND range(0, 10) AS it
MATCH (c:Classifier) WHERE rand() > 0.7
WITH it, ux_classifiers, ux_features, ux_title, COLLECT(c.id) AS classifiers, COLLECT(1.0) AS features, COLLECT(c.keyword) AS title
RETURN ux_title, title, alg.classifiers.similar(ux_classifiers, ux_features, classifiers, features) AS score
ORDER BY score DESC

Не понимаю, почему нормализация по сумме не будет делать того же самого.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории