Комментарии 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
радикально больше, чем у вас.
В сравнении участвуют только классификаторы отдельно взятого поста и пользователя
А вы уверены, что получающиеся результаты (дистанции, полученные в разных пространствах) корректно сравнивать между собой?
За случайный минус прошу простить - ткнул с телефона мимо, плюсанул в карму в качестве извинений.
Для второй части вектора применим те самые действия, что и для первого, и уравновесим их, приводя их максимумы к одному общему знаменателю по следующей формуле: 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
Проектирование алгоритма под рекомендательную систему