【问题标题】:neo4j percentage of attribute for social network社交网络的 neo4j 属性百分比
【发布时间】:2017-11-27 13:55:53
【问题描述】:

如何计算社交网络所有连接的属性百分比? 在这个特定的示例中,我想通过评估用户的交互(电话、短信)来计算用户的欺诈行为:

CREATE (Alice:Person {id:'a', fraud:1})
CREATE (Bob:Person {id:'b', fraud:0})
CREATE (Charlie:Person {id:'c', fraud:0})
CREATE (David:Person {id:'d', fraud:0})
CREATE (Esther:Person {id:'e', fraud:0})
CREATE (Fanny:Person {id:'f', fraud:0})
CREATE (Gabby:Person {id:'g', fraud:0})
CREATE (Fraudster:Person {id:'h', fraud:1})


CREATE
  (Alice)-[:CALL]->(Bob),
  (Bob)-[:SMS]->(Charlie),
  (Charlie)-[:SMS]->(Bob),
  (Fanny)-[:SMS]->(Charlie),
  (Esther)-[:SMS]->(Fanny),
  (Esther)-[:CALL]->(David),
  (David)-[:CALL]->(Alice),
  (David)-[:SMS]->(Esther),
  (Alice)-[:CALL]->(Esther),
  (Alice)-[:CALL]->(Fanny),
  (Fanny)-[:CALL]->(Fraudster)

当尝试查询时:

MATCH (a)-->(b)
WHERE b.fraud = 1
RETURN (count() / ( MATCH (a) -->(b) RETURN count() ) * 100)

我看到以下错误:

Invalid input '>': expected 0..9, '.', UnsignedHexInteger, UnsignedOctalInteger or UnsignedDecimalInteger (line 3, column 33 (offset: 66))
"RETURN (count() / ( MATCH (a) -->(b) RETURN count() ) * 100)"
                                 ^

【问题讨论】:

    标签: graph neo4j cypher


    【解决方案1】:

    此查询将返回每个欺诈的连接百分比:

    MATCH (:Person)-[:CALL|:SMS]->(f:Person)
    WITH TOFLOAT(COUNT(*))/100 AS divisor, COLLECT(f) AS fs
    UNWIND fs AS f
    WITH divisor, f
    WHERE f.fraud = 1
    RETURN f, COUNT(*)/divisor AS percentage
    

    有了样本数据,结果是:

    +----------------------------------------------+
    | f                        | percentage        |
    +----------------------------------------------+
    | Node[13]{id:"h",fraud:1} | 9.090909090909092 |
    | Node[6]{id:"a",fraud:1}  | 9.090909090909092 |
    +----------------------------------------------+
    

    此查询只需要对数据库进行一次扫描,并且明确说明节点标签和关系类型——以过滤掉数据库中可能存在的任何其他数据。

    【讨论】:

    • 太棒了。是否也可以根据百分比对 Neo4j 图中的节点进行着色?它似乎只在表格视图中可用 - 而不是在图形可视化中。另外:[:CALL|:SMS*1..3] 是针对多个级别的正确方法吗?您提到了性能:是否有可能在图表上单次传递执行 3 种类型的聚合(全部 - 就像您所做的那样,只有短信,只有电话)?
    • neo4j 浏览器 UI 仅允许您按标签设置节点着色,而不是按属性值。而且,是的,您可以将 [:CALL|:SMS*..3] 用于 1 到 3 个匹配关系之间的路径。
    • 至于另外2种聚合方式,不清楚你想要什么。您是否只对每个关系都具有相同类型的路径(最多 3 个关系)感兴趣?
    • 或多或少:我不希望复制粘贴上面的通话或短信、通话、短信的语句并在图上运行 3 次。
    • 我看到 stackoverflow.com/questions/12269009/… 概述了如何组合多个 MATCH 子句 - 开始应该没问题。
    【解决方案2】:

    在您的 RETURN 部分中,您调用一个新查询:MATCH (a) -->(b) RETURN count()

    这在 Neo4j 中是不允许的,您应该使用 WITH 关键字进行子查询:

    MATCH ()-->() 
    WITH count(*) AS total
      MATCH ()-->(b)
      WHERE b.fraud = 1
      RETURN toFloat(count(*)) / total * 100
    

    或者在您的情况下,因为您只想要数据库中的关系总数,您可以进行以下查询:

    MATCH ()-->(b)
    WHERE b.fraud = 1
    RETURN toFloat(count(*)) / size(()-->()) * 100
    

    更新

    • 在密码查询中添加toFloat,否则除法会给出整数而不是浮点数

    【讨论】:

    • count() 正在投掷:Insufficient parameters for function 'count'
    • 没问题,但这只是考虑直接邻居。如果我想(迭代地)进入每个用户的网络 - 让我们假设深度为 3。这如何集成?此外,返回的结果是 0,这对我来说似乎很奇怪。
    • 哈,当然,两个整数的除法是整数而不是浮点数……我会更正我的回答
    • 对于您的第二点,您只需像这样更改图形模式:()-[*..3]->(b)
    • 这样更好,但只返回整个网络的标量值,我希望得到每个顶点的单独值。
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多