Кажется, вы на правильном пути с вашим запросом. Тем не менее, я хочу упомянуть пару вещей относительно сходства текста и указать вам пару ссылок, которые могут быть полезны для дальнейшего изучения:
TF-IDF
Подсчет похожих слов в общем случае приведет к плохим результатам. В области поиска информации распространенным методом измерения сходства на основе слов является TF / IDF:
Мера проста, TF - это термин частота в конкретном документе. Есть несколько вариантов, но давайте возьмем простую, частоту терминов для данного предложения: Today I went to the shopping center and then went back to home
TF для слова shopping
равен единице, а для to
- 2.
Частота обратных документов (IDF) определяет значение этого слова:
idf(word, document) = log ( total number of documents / number of documents containing that word )
TF-IDF рассчитывается как
tf-idf(word, document, corpus) = tf(word, doc) . idf(word, corpus)
Таким образом, слово в конкретном документе будет иметь больший tf-idf, если tf высокий, а idf низкий.
Теперь вернемся к вашему варианту использования, сравнивая два FreeTextResponse
, вы также можете вычислить, насколько tf-idf общих слов закрыт друг для друга:
FTR => FreeTextResponse
similarity(ftr1, ftr2, wordA) = 1 - ( tf-idf(wordA, ftr1) - tf-idf(wordA, ftr2) )
Небольшое объяснение на английском языке: если у меня есть документ, где dog
появляется 12 раз, и другой документ, где он появляется 1 раз, то эти два документа, возможно, не говорят об одном и том же.
Обратите внимание, что мы обычно используем вариант TF / IDF с учетом длины документа, более подробную информацию можно найти по ссылке в Википедии.
* Игнорируемые слова 1046 *
Во-вторых, не все слова имеют смысл. Это то, что мы называем stopwords
, и они могут быть отброшены во время сопоставления сходства или даже не вставлены в график вообще. Эти слова, например, для: the, it, a,...
Если вы возьмете в качестве примера поисковую систему Lucene (которая является основой Elastic и Solr), вы можете найти список стоп-слов по умолчанию для английского языка в анализаторе:
static {
final List<String> stopWords = Arrays.asList(
"a", "an", "and", "are", "as", "at", "be", "but", "by",
"for", "if", "in", "into", "is", "it",
"no", "not", "of", "on", "or", "such",
"that", "the", "their", "then", "there", "these",
"they", "this", "to", "was", "will", "with"
);
....
Похожие слова
На диаграмме показаны слова, связанные друг с другом отношением SIMILAR_TO
с показателем сходства.
Они также могут быть использованы для поиска сходства, конечно, вы должны учитывать глубину, чтобы уменьшить сходство.
Заключение
В целом, я бы не стал делать все в одном запросе Cypher. Я бы действительно попытался найти то, что делает два документа похожими в вашем конкретном домене, а затем объединить результаты нескольких запросов Cypher с вашим любимым языком программирования.
Вы также можете взглянуть на некоторые расширения Neo4j, которые могут упростить и улучшить вашу текстовую аналитику, например https://github.com/graphaware/neo4j-nlp