Graph Neo4j字图查询
我已经创建了一个Neo4j的Graph Neo4j字图查询,graph,neo4j,cypher,Graph,Neo4j,Cypher,我已经创建了一个Neo4j的问卷完成图,其中可能有一个或多个FreeTextResponse答案。每个FreeTextResponse中都有任意数量的Words Words与图形中的其他Words相关,其中与具有similarityValue属性的关系表示词语在语义上的相似程度 任何数量的FreeTextResponses都可以链接到Words 最后,我想根据FreeTextResponse答案的相似性,找到相关问卷的集群 我的第一步似乎是编写一个查询,该查询从问卷完成节点遍历图形,通过Free
问卷
完成图,其中可能有一个或多个FreeTextResponse
答案。每个FreeTextResponse
中都有任意数量的Word
s
Word
s与图形中的其他Word
s相关,其中与具有similarityValue
属性的关系表示词语在语义上的相似程度
任何数量的FreeTextResponse
s都可以链接到Word
s
最后,我想根据FreeTextResponse
答案的相似性,找到相关问卷的集群
我的第一步似乎是编写一个查询,该查询从问卷
完成节点遍历图形,通过FreeTextResponse
答案,通过word
s,通过那些word
s也存在的任何FreeTextResponse
答案
然后再次进行相同操作,但通过两个或多个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
看来您的查询进展顺利。然而,我想提及一些关于文本相似性的事情,并为您指出一些可能对进一步学习有用的链接:
TF-IDF
计算相似单词的出现次数通常会导致较差的结果。在信息检索领域,基于单词的相似度度量的常用技术是TF/IDF:
度量方法很简单,TF是特定文档中的术语频率。有多种变体,但让我们以简单的一种为例,即给定句子的原始术语频率:今天我去了购物中心,然后回家了
单词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的基础)为例,您可以在analyzer中找到英语的默认停止词列表:
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"
);
....
静态{
最终列表stopWords=Arrays.asList(
“a”、“an”、“and”、“are”、“as”、“at”、“be”、“but”、“by”,
“for”、“if”、“in”、“into”、“is”、“it”,
“不”、“不”、“属于”、“关于”、“或”、“诸如此类”,
“那个”,“那个”,“他们的”,“然后”,“那里”,“这些”,
“他们”、“这个”、“到”、“过去”、“将来”、“与”
);
....
相似的词
在您的图表中,您通过一个类似于
的关系和一个相似性分数来显示彼此相关的单词
这些也可以用来寻找相似性,当然,你应该考虑到深度,以减少相似性
结论
总的来说,我不会专注于在一个Cypher查询中实现所有功能。我会真正专注于尝试找出在您的特定领域中两个文档的相似之处,然后将多个Cypher查询的结果与您最喜欢的编程语言结合起来
您还可以查看一些Neo4j扩展,它们可能会简化和改进您的文本分析,例如我不明白您对频率部分做了什么…事实上,您可以详细说明一个单词的评分机制吗?谢谢您的回复。频率是指一个单词
的出现次数两个调查问卷中的sts。目的是使用它来计算一个百分比,该百分比可用于对调查问卷的相关性进行排序。谢谢!我不知道“GraphAware自然语言处理”模块。我刚刚玩过它们,它们正是我需要的。非常感谢!