在向图形添加边之前对余弦相似度分数进行排序
Sort cosine similarity scores before adding edges to graph
我试图让 jaccard similarity found 的示例用于余弦相似度,但想将创建的 links 的数量限制在前 10 个分数。
我查看了 https://gist.github.com/dkuppitz/79e0b009f0c9ae87db5a,但无法弄清楚如何跳过边缘创建部分以在之前对其进行排序并获得与上述 link 相同的结果。
基于上面的 jaccard 示例,这是我目前得出的结论:
g.V().
match(
__.as('v1').outE('RECOMMENDS').values('amount').fold().as('v1rec'),
__.as('v1').V().as('v2'),
__.as('v2').outE('RECOMMENDS').values('amount').fold().as('v2rec'),
__.as('v1').out().dedup().fold().as('v1n'),
__.as('v2').out().dedup().fold().as('v2n')
).
where('v1',lt('v2')).
by(id).
where('v1',neq('v2').and(without('v1n'))).
where('v2',without('v1n')).
project('v1','v2','n','d1','d2').
by(select('v1')).
by(select('v2')).
by(
select('v1rec','v2rec') <-- this does not work, can't get dot product from this
).
by(coalesce(
select('v1rec').
unfold().
math('_ ^ 2').
sum(),
constant(0))).
by(coalesce(
select('v2rec').
unfold().
math('_ ^ 2').
sum(),
constant(0))).
filter(select('d1').is(gt(0))).
filter(select('d2').is(gt(0))).
project('v1','v2','cosine').
by(select('v1')).
by(select('v2')).
by(math('n/(sqrt(d1)*sqrt(d2))')).
sort{-it.cosine}.
toList()[0..9].
each {
r -> g.V(r['v2']).as('v2').
V(r['v1']).
addE('PREDICTED_COSINE').
to('v2').
property('score', r['cosine']).
toList()
}
但无法弄清楚如何通过 select('v1rec','v2rec') 逐步获得第三步中的点积。请帮忙。
更新:
我无法将其放入评论中,因此在此处发布:
我尝试了另一种让我更接近(我认为)的方法,但在迭代每个地图列表以从每个地图中提取值时仍然存在问题:
g.V().
match(
__.as('v1').outE().as('e1'),
__.as('v1').V().as('v2'),
__.as('v2').outE().as('e2'),
__.as('v1').out().dedup().fold().as('v1n'),
__.as('v2').out().dedup().fold().as('v2n')).
where('v1',neq('v2').
and(without('v1n'))).
where('v2',without('v1n')).
project('v1','v2','a1','a2').
by(select('v1')).
by(select('v2')).
by(select('e1').by('amount')).
by(select('e2').by('amount')).
project('v1','v2','n','d1','d2').
by(select('v1')).
by(select('v2')).
by(math('a1 * a2')).
by(math('a1 * a1')).
by(math('a2 * a2')).
group().
by(select('v1','v2')).
unfold()
一行输出:
==>{v1=v[4240], v2=v[8320]}=[{v1=v[4240], v2=v[8320], n=210.0, d1=196.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=182.0, d1=196.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=182.0, d1=196.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=45.0, d1=9.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=45.0, d1=9.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}]
我的目标是对地图中的所有 "n"、"d1" 和 "d2" 值求和,这样我就可以计算相似度为 sum(n)/(sqrt( sum(d1))*sqrt(sum(d2))) 对于每个键(例如 {v1=v[4240], v2=v[8320]} 在示例列表之外所以 n 将是 210 + 182 + 182 + 45 + 39 + 39 + 45 + 39 + 39 = 820)。我想为一堆图表执行此操作,因此我没有专门针对此的图表。现在明白了吗?
这是我最终想出的:
g.V().
match(
__.as('v1').outE().as('e1'),
__.as('v1').V().as('v2'),
__.as('v2').outE().as('e2'),
__.as('v1').out().dedup().fold().as('v1n'),
__.as('v2').out().dedup().fold().as('v2n')
).
where('v1',neq('v2').
and(without('v1n'))).
where('v2',without('v1n')).
project('v1','v2','a1','a2').
by(select('v1')).
by(select('v2')).
by(select('e1').by('amount')).
by(select('e2').by('amount')).
project('v1','v2','n','d1','d2').
by(select('v1')).
by(select('v2')).
by(math('a1 * a2')).
by(math('a1 * a1')).
by(math('a2 * a2')).
group().
by(select('v1','v2')).
unfold().
project('v1','v2','n','d1','d2').
by(select(keys).select('v1')).
by(select(keys).select('v2')).
by(select(values).local(unfold().select('n').sum())).
by(select(values).local(unfold().select('d1').sum())).
by(select(values).local(unfold().select('d2').sum())).
project('v1','v2','c').
by(select('v1')).
by(select('v2')).
by(math('n / (sqrt(d1) * sqrt(d2))')).
sort{ -it.c }.
toList()[0..9]
感谢大家的帮助。
我试图让 jaccard similarity found
我查看了 https://gist.github.com/dkuppitz/79e0b009f0c9ae87db5a,但无法弄清楚如何跳过边缘创建部分以在之前对其进行排序并获得与上述 link 相同的结果。
基于上面的 jaccard 示例,这是我目前得出的结论:
g.V().
match(
__.as('v1').outE('RECOMMENDS').values('amount').fold().as('v1rec'),
__.as('v1').V().as('v2'),
__.as('v2').outE('RECOMMENDS').values('amount').fold().as('v2rec'),
__.as('v1').out().dedup().fold().as('v1n'),
__.as('v2').out().dedup().fold().as('v2n')
).
where('v1',lt('v2')).
by(id).
where('v1',neq('v2').and(without('v1n'))).
where('v2',without('v1n')).
project('v1','v2','n','d1','d2').
by(select('v1')).
by(select('v2')).
by(
select('v1rec','v2rec') <-- this does not work, can't get dot product from this
).
by(coalesce(
select('v1rec').
unfold().
math('_ ^ 2').
sum(),
constant(0))).
by(coalesce(
select('v2rec').
unfold().
math('_ ^ 2').
sum(),
constant(0))).
filter(select('d1').is(gt(0))).
filter(select('d2').is(gt(0))).
project('v1','v2','cosine').
by(select('v1')).
by(select('v2')).
by(math('n/(sqrt(d1)*sqrt(d2))')).
sort{-it.cosine}.
toList()[0..9].
each {
r -> g.V(r['v2']).as('v2').
V(r['v1']).
addE('PREDICTED_COSINE').
to('v2').
property('score', r['cosine']).
toList()
}
但无法弄清楚如何通过 select('v1rec','v2rec') 逐步获得第三步中的点积。请帮忙。
更新:
我无法将其放入评论中,因此在此处发布:
我尝试了另一种让我更接近(我认为)的方法,但在迭代每个地图列表以从每个地图中提取值时仍然存在问题:
g.V().
match(
__.as('v1').outE().as('e1'),
__.as('v1').V().as('v2'),
__.as('v2').outE().as('e2'),
__.as('v1').out().dedup().fold().as('v1n'),
__.as('v2').out().dedup().fold().as('v2n')).
where('v1',neq('v2').
and(without('v1n'))).
where('v2',without('v1n')).
project('v1','v2','a1','a2').
by(select('v1')).
by(select('v2')).
by(select('e1').by('amount')).
by(select('e2').by('amount')).
project('v1','v2','n','d1','d2').
by(select('v1')).
by(select('v2')).
by(math('a1 * a2')).
by(math('a1 * a1')).
by(math('a2 * a2')).
group().
by(select('v1','v2')).
unfold()
一行输出:
==>{v1=v[4240], v2=v[8320]}=[{v1=v[4240], v2=v[8320], n=210.0, d1=196.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=182.0, d1=196.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=182.0, d1=196.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=45.0, d1=9.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=45.0, d1=9.0, d2=225.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}, {v1=v[4240], v2=v[8320], n=39.0, d1=9.0, d2=169.0}]
我的目标是对地图中的所有 "n"、"d1" 和 "d2" 值求和,这样我就可以计算相似度为 sum(n)/(sqrt( sum(d1))*sqrt(sum(d2))) 对于每个键(例如 {v1=v[4240], v2=v[8320]} 在示例列表之外所以 n 将是 210 + 182 + 182 + 45 + 39 + 39 + 45 + 39 + 39 = 820)。我想为一堆图表执行此操作,因此我没有专门针对此的图表。现在明白了吗?
这是我最终想出的:
g.V().
match(
__.as('v1').outE().as('e1'),
__.as('v1').V().as('v2'),
__.as('v2').outE().as('e2'),
__.as('v1').out().dedup().fold().as('v1n'),
__.as('v2').out().dedup().fold().as('v2n')
).
where('v1',neq('v2').
and(without('v1n'))).
where('v2',without('v1n')).
project('v1','v2','a1','a2').
by(select('v1')).
by(select('v2')).
by(select('e1').by('amount')).
by(select('e2').by('amount')).
project('v1','v2','n','d1','d2').
by(select('v1')).
by(select('v2')).
by(math('a1 * a2')).
by(math('a1 * a1')).
by(math('a2 * a2')).
group().
by(select('v1','v2')).
unfold().
project('v1','v2','n','d1','d2').
by(select(keys).select('v1')).
by(select(keys).select('v2')).
by(select(values).local(unfold().select('n').sum())).
by(select(values).local(unfold().select('d1').sum())).
by(select(values).local(unfold().select('d2').sum())).
project('v1','v2','c').
by(select('v1')).
by(select('v2')).
by(math('n / (sqrt(d1) * sqrt(d2))')).
sort{ -it.c }.
toList()[0..9]
感谢大家的帮助。