Как создать словарный график с векторами слов, используя neo4j?

Я хочу создать словарный граф с векторами слов. Цель состоит в том, чтобы запросить ближайшее слово в словарном графике на основе сходства слов. Как мы можем добиться этого на neo4j?

Пример:

Предположим, словарь состоит из следующего:

Product Quality
Wrong Product
Product Price
Product Replacement

И слово запроса: Affordable Product

В одном запросе я должен быть в состоянии выяснить, что «Доступный продукт» более тесно связан с «Ценой продукта», чем любые другие.

Обратите внимание, что я сохраняю встраивание слов в граф, и, следовательно, проверка косинусного подобия для каждого слова в словаре по одному поможет мне достичь этого. Однако, когда словарный запас становится большим, выполнение запросов по одному снижает скорость и производительность.

Если есть какой-либо способ сохранить вложения слов для словаря предметной области в виде графа, который можно запросить для ближайшего узла на основе косинусного сходства, это может быть возможным решением. Однако пока ничего подобного найти не удалось.

С нетерпением жду указателей, если таковые имеются. Спасибо


person buddy    schedule 16.05.2020    source источник
comment
Термин вашего запроса 'Affordable Product' отсутствует в вашем словаре. (Технически даже не 'Product', так как вы упомянули только токены, которые включают 2 слова.) На мгновение отложив в сторону любые проблемы со скоростью или возможные особенности (например, графическую базу данных), как вы ожидали, что код оценит неизвестный термин 'Affordable Product' ближе всего к 'Product Price'? (Есть ли у вас существующее решение для этого, которое слишком медленно, что вызывает ваш запрос о построении графика?   -  person gojomo    schedule 16.05.2020
comment
Я буду хранить косинусное расстояние ко всем остальным узлам на графике. Это была самая грубая реализация, которую я мог придумать.   -  person buddy    schedule 18.05.2020
comment
Какие узлы в каком графе? Оставив в стороне любые проблемы со скоростью или возможные особенности (например, структуру графика), как вы ожидали, что код оценит неизвестный термин «Доступный продукт», наиболее близкий к «Цена продукта»? (Есть ли у вас существующее решение для этого, которое слишком медленно, что вызывает ваш запрос о построении графа? Наличие способа сделать это неизвестное сравнение с известным, даже без какой-либо оптимизации структуры графа, является необходимым условием для рассмотрения других подходит как предварительно рассчитанный график ближайших соседей.)   -  person gojomo    schedule 18.05.2020
comment
Я использую косинусное расстояние, чтобы найти близость. Я могу сделать это со всеми узлами в пространстве графа, чтобы найти ближайший   -  person buddy    schedule 19.05.2020
comment
Если термин 'Affordable Product' (эта точная строка из двух слов) отсутствует в вашем словаре, для него есть вектор для вычисления косинусного расстояния.   -  person gojomo    schedule 20.05.2020
comment
Я не понял. Это был вопрос?   -  person buddy    schedule 20.05.2020
comment
Э-э, это должно было сказать, что для вычисления косинусного расстояния не существует вектора *no. Да, чтобы понять ваш вопрос и цели, у меня все еще есть вопросы: отложив на мгновение любые проблемы со скоростью или возможные особенности (например, графическую базу данных), как вы ожидали, что код будет оценивать неизвестный термин «Доступный продукт» ближайший к "Цена продукта"? И: есть ли у вас существующее решение для этого, которое слишком медленно, что вызывает ваш запрос о построении графика?   -  person gojomo    schedule 20.05.2020
comment
Я предполагаю, что у вас есть начальный словарь (о котором вы упомянули), для которого есть векторы (о которых вы упомянули). Но у вас еще нет графика (о котором вы спрашиваете), и еще не ясно, как наличие графика решит вашу примерную проблему (потому что наличие графика само по себе не поможет сделать неизвестный термин без вектора, такого как 'Affordable Product' сопоставимо с известным термином, таким как 'Product Price'). Если это проблема, графики не имеют значения, но было бы хорошо знать, что вы пробовали. Но если есть какая-то другая реальная причина для графика, это тоже было бы полезно знать.   -  person gojomo    schedule 20.05.2020
comment
На самом деле настоящая причина, по которой я ищу график, состоит в том, чтобы увидеть, могу ли я быстро запросить ближайшую метку для новой метки. В противном случае я буду сравнивать по одному, что занимает много времени.   -  person buddy    schedule 21.05.2020
comment
Но если это new label, то его нет ни в полном словаре векторов, ни в графе. Даже если каким-то неопределенным образом вы загрузите для него вектор, его все равно нет на графике. Если вы хотите найти одно существующее слово, которое ближе всего, это полная проверка всех известных слов. После того, как вы это сделаете, нет необходимости в графе кеша ближайших соседей каждого слова - вы уже сделали сложную часть. (Но также: если массовое сравнение один за другим кажется слишком трудоемким, возможно, вы делаете это плохо — отсюда и мой вопрос о том, что вы пробовали, и почему вы пришли к выводу, что это слишком медленно.)   -  person gojomo    schedule 21.05.2020
comment
Есть способы сделать массовое сравнение лучше! Есть и другие оптимизации для других целей. Но чтобы сделать хорошее предложение, мне нужно знать, где вы на самом деле находитесь - какие данные у вас есть, что вы пробовали и нашли слишком медленным, какова реальная конечная цель. Не более подробностей одного гипотетического решения, словарного графа. Это может иметь какое-то применение, но, похоже, не соответствует вашим потребностям. Он обычно не используется для быстрого поиска ближайшего... по косинусному сходству, за исключением некоторых экстремальных ситуаций, когда точные результаты продаются из-за проблем в многомерных пространствах.   -  person gojomo    schedule 21.05.2020
comment
Мне еще предстоит полностью опробовать различные варианты этого подхода. Совсем новичок с neo4j. Я открыт и для других вариантов, если таковые имеются.   -  person buddy    schedule 22.05.2020
comment
Есть несколько вариантов, которые я мог бы предложить, если бы вы могли подробнее объяснить детали потребностей и вещей, которые я просил.   -  person gojomo    schedule 22.05.2020
comment
Позвольте мне рассказать, чего я пытаюсь достичь, что может помочь в нашем обсуждении. Я пытаюсь пометить короткий текст наиболее подходящей темой из словаря тем. Я пытаюсь придумать масштабируемую модель, которую я могу создать и использовать для любой области. До сих пор я вел список тем и сравнивал их одно за другим с предложениями, чтобы найти, какая тема лучше всего подходит. Однако по мере того, как словарный запас становится большим, это очень медленный процесс.   -  person buddy    schedule 23.05.2020
comment
Причина изучения neo4j заключалась в том, чтобы посмотреть, смогу ли я создать кураторский словарь любой области и смогу ли я найти ближайший тег к предложению с помощью одного запроса. Поскольку я новичок в этом, я не уверен, правильный ли подход или направление, в котором нужно полностью следовать. Дайте мне знать, если какая-либо другая информация поможет   -  person buddy    schedule 23.05.2020
comment
То, что вы описали, похоже на процесс классификации текстов: у вас есть тексты, вы хотите, чтобы они были помечены из некоторого фиксированного набора категорий. (Возможно, каждый текст получает одну метку, может быть, несколько с разным весом достоверности.) Плотные векторы слов/документов, такие как из Word2Vec или Doc2Vec, могут стать полезной частью решения, но предварительная загрузка графовой базы данных, скорее всего, не будет. Я предлагаю найти онлайн-примеры классификации текста, которые кажутся похожими на ваши потребности (независимо от того, используют ли они слова-векторы или нет), и адаптировать их.   -  person gojomo    schedule 23.05.2020


Ответы (2)


Что вы хотите сделать, так это сохранить результаты встраивания в график. Следующим шагом является использование библиотеки Neo4j Graph Data Science и запуск конкретно алгоритм подобия косинуса. Это должно выглядеть примерно так:

MATCH (p:Word)
 WITH {item:id(p), weights: p.embedding} AS wordData
 WITH collect(wordData) AS data
 CALL gds.alpha.similarity.cosine.write({
   nodeProjection: '*',
   relationshipProjection: '*',
   data: data,
   // here is where you define how many nearest neighbours should be stored
   topK: 1,
   // here you define what is the minimal similarity between a 
   // given pair of node to be still relevant
   similarityCutoff: 0.1
 })
 YIELD nodes, similarityPairs, writeRelationshipType, writeProperty, min, max, mean, stdDev, p25, p50, p75, p90, p95, p99, p999, p100
 RETURN nodes, similarityPairs, writeRelationshipType, writeProperty, min, max, mean, p95

Теперь вы предварительно обработали своих ближайших соседей и можете легко запросить их, например:

MATCH (w:Word)-[:SIMILAR]-(other)
RETURN other

Надеюсь, это поможет, дайте мне знать, если у вас есть другие вопросы.

person Tomaž Bratanič    schedule 20.05.2020

После опробования и прочтения нескольких вариантов я обнаружил, что https://github.com/facebookresearch/faiss лучший вариант для этого варианта использования.

person buddy    schedule 27.06.2020