我创建了一个由Questionnaire
完成的Neo4j图,其中可能有1个或多个FreeTextResponse
答案。每个FreeTextResponse
中都有任意数量的Word
。
Word
与图中的其他Word
相关,具有IS_RELATED_TO
关系,该关系具有similarityValue
属性,表示单词在语义上的相似程度。
任意数量的FreeTextResponse
可以链接到Word
。
最终,我想根据Questionnaire
答案的相似性来找到相关的FreeTextResponse
完成的聚类。
我的第一步似乎是编写一个查询,该查询从Questionnaire
完成节点,FreeTextResponse
答案,word
和所有{ {1}}回答说这些FreeTextResponse
也存在。
再次如此,但是要通过两个或更多Word
节点来完成,并根据它们的累积相似度值计算权重。
图形结构如下:
我已经尝试了多种方法,但是正在努力应对各种变量。
我第一步的最佳尝试是:
word
...但是我不确定我是否相信结果,并且我不认为他们考虑到match (qr:Questionnaire{QuestionnaireReturnID:186406})<-[:IN]-(ftr:FreeTextResponse)<-[:IN]-(w1:WordGraph_Word)-[:IN]->(ftr2:FreeTextResponse)-[:IN]->(qr2:Questionnaire)
WITH qr2, ftr, count(distinct w1) as frequency
WITH distinct qr2, length(split((ftr.fullSentenceString), ' ')) as wordCount, frequency
WITH
COLLECT({
QuestionnaireReturnID: qr2.QuestionnaireReturnID,
frequency: frequency,
wordCount: wordCount,
percentageMatch: (toFloat(frequency) / toFloat(wordCount)) * 100
}) as associatedQuestionnaires
UNWIND(associatedQuestionnaires) as a
WITH a order by a.percentageMatch desc where a.percentageMatch > 15
return a
可以有任意数量的FreeTextResponse
。>
请问解决此类问题的最佳方法是什么?
谢谢!
更新:
我想我可能已经制定了步骤1,如下所示链接了直接链接的Questionnaire
:
Questionnaire
答案 0 :(得分:3)
看来您的查询进展顺利。但是,我想谈谈关于文本相似性的几件事,并为您提供一些可能对进一步学习有用的链接:
TF-IDF
计算相似的单词出现次数通常会导致较差的结果。在信息检索领域,一种基于单词的相似度测量常用技术是TF / IDF:
测量很简单,TF是特定文档中的频率一词。有多种变体,但让我们以一个简单的,给定句子的原始术语频率为例:Today I went to the shopping center and then went back to home
shopping
的TF为1,而to
的TF为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的变体,考虑到文档的长度,更多信息请参阅Wikipedia链接。
关键词
第二,并非所有单词都是有意义的。这就是我们所说的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