Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

GraphTalk Helsinki - Fraud Analysis with Neo4j

Jesus Barrasa, Neo4j
GraphTalk Helsinki

  • Login to see the comments

  • Be the first to like this

GraphTalk Helsinki - Fraud Analysis with Neo4j

  1. 1. Fraud Analysis with Neo4j GraphTalk Helsinki Sep 19, 2019 Dr. Jesús Barrasa Neo4j @BarrasaDV
  2. 2. May 2016…
  3. 3. ...11.5M documents, 2.6 TB!
  4. 4. May 2016… https://offshoreleaks.icij.org/pages/database
  5. 5. What did we learn from the Panama Papers?
  6. 6. Look at this dataset
  7. 7. Swap glasses
  8. 8. Look at the dataset again
  9. 9. Do I have a graph problem?
  10. 10. Law of the instrument (of the hammer) : cognitive bias that involves an over-reliance on a familiar tool. A.Maslow 1966
  11. 11. Did Google have a graph problem back in the early 2000s? I’d say it was an information retrieval problem
  12. 12. nd so, my fellow graphistas: ask not whether you have a graph problem - instead, look at your problem with a graph thinking mindset” J. Barrasa - Graph Connect Europe 2017 “A
  13. 13. Example 1: Credit card fraud origination and assessment of potential impact
  14. 14. Mark Robert Sheila Kate
  15. 15. WITH { amount: 2.50, currency:"USD", txid:"05015244006", mid:"5073047", tid:"5073440-7", timestamp:1490060618007, cardno:"5224654370862586050" } AS newTxData MATCH (lastTx:Transaction { cardno: newTxData.cardno }) WHERE NOT (lastTx)-[:NEXT]->() CREATE (newTx:Transaction) SET newTx += newTxData CREATE (lastTx)-[:NEXT]->(newTx) WITH newTx, newTxData MERGE (term:Terminal { tid: newTxData.tid}) CREATE (newTx)-[:IN_TERMINAL]->(term) Tx Tx Tx Tx Fraud Fraud Data load: Transactions
  16. 16. WITH { amount: 2.50, currency:"USD", txid:"05015244006", mid:"5073047", tid:"5073440-7", timestamp:1490060618007, cardno:"5224654370862586050" } AS newTxData MATCH (lastTx:Transaction { cardno: newTxData.cardno }) WHERE NOT (lastTx)-[:NEXT]->() CREATE (newTx:Transaction) SET newTx += newTxData CREATE (lastTx)-[:NEXT]->(newTx) WITH newTx, newTxData MERGE (term:Terminal { tid: newTxData.tid}) CREATE (newTx)-[:IN_TERMINAL]->(term) Tx Tx Tx Tx Fraud Fraud Data load: Transactions
  17. 17. WITH { amount: 2.50, currency:"USD", txid:"05015244006", mid:"5073047", tid:"5073440-7", timestamp:1490060618007, cardno:"5224654370862586050" } AS newTxData MATCH (lastTx:Transaction { cardno: newTxData.cardno }) WHERE NOT (lastTx)-[:NEXT]->() CREATE (newTx:Transaction) SET newTx += newTxData CREATE (lastTx)-[:NEXT]->(newTx) WITH newTx, newTxData MERGE (term:Terminal { tid: newTxData.tid}) CREATE (newTx)-[:IN_TERMINAL]->(term) Tx Tx Tx Tx Fraud Fraud Data load: Transactions
  18. 18. WITH { amount: 2.50, currency:"USD", txid:"05015244006", mid:"5073047", tid:"5073440-7", timestamp:1490060618007, cardno:"5224654370862586050" } AS newTxData MATCH (lastTx:Transaction { cardno: newTxData.cardno }) WHERE NOT (lastTx)-[:NEXT]->() CREATE (newTx:Transaction) SET newTx += newTxData CREATE (lastTx)-[:NEXT]->(newTx) WITH newTx, newTxData MERGE (term:Terminal { tid: newTxData.tid}) CREATE (newTx)-[:IN_TERMINAL]->(term) Tx Tx Tx Tx Fraud Fraud Data load: Transactions
  19. 19. WITH { txid:"0501524400006"} AS unrecognizedTx MATCH (tx:Transaction { txid: unrecognizedTx.txid }) SET tx:FraudTx Tx Tx Tx Tx Fraud Fraud Data load: Reported fraud
  20. 20. WITH { txid:"0501524400006"} AS unrecognizedTx MATCH (tx:Transaction { txid: unrecognizedTx.txid }) SET tx:FraudTx Tx Tx Tx Tx Fraud Fraud Data load: Reported fraud
  21. 21. WITH { txid:"0501524400006"} AS unrecognizedTx MATCH (tx:Transaction { txid: unrecognizedTx.txid }) SET tx:FraudTx Tx Tx Tx Tx Fraud Fraud Data load: Reported fraud
  22. 22. WITH { txid:"0501524400006"} AS unrecognizedTx MATCH (tx:Transaction { txid: unrecognizedTx.txid }) SET tx:FraudTx Tx Tx Tx Tx Fraud Fraud Data load: Reported fraud
  23. 23. MATCH (term:Terminal)<-[:IN_TERMINAL]-(t)-[n:NEXT*]->(:FraudTx) WITH term , count(distinct t.cardno) as ct, min(t.timestamp) as mindate, max(t.timestamp) as maxdate WHERE ct > 1 MATCH (term)<-[:IN_TERMINAL]-(otherTx) WHERE otherTx.timestamp < maxdate and otherTx.timestamp > mindate RETURN term.tid AS terminal,mindate,maxdate, 100 * ct / COUNT(DISTINCT otherTx.cardno) AS impact, (maxdate - mindate)/(24*3600000) as timewindow ORDER BY impact DESC, timewindow DESC Query: Fraud origination at terminal level
  24. 24. MATCH (term:Terminal)<-[:IN_TERMINAL]-(t)-[n:NEXT*]->(:FraudTx) WITH term , count(distinct t.cardno) as ct, min(t.timestamp) as mindate, max(t.timestamp) as maxdate WHERE ct > 1 MATCH (term)<-[:IN_TERMINAL]-(otherTx) WHERE otherTx.timestamp < maxdate and otherTx.timestamp > mindate RETURN term.tid AS terminal,mindate,maxdate, 100 * ct / COUNT(DISTINCT otherTx.cardno) AS impact, (maxdate - mindate)/(24*3600000) as timewindow ORDER BY impact DESC, timewindow DESC Query: Fraud origination at terminal level
  25. 25. MATCH (term:Terminal)<-[:IN_TERMINAL]-(t)-[n:NEXT*]->(:FraudTx) WITH term , count(distinct t.cardno) as ct, min(t.timestamp) as mindate, max(t.timestamp) as maxdate WHERE ct > 1 MATCH (term)<-[:IN_TERMINAL]-(otherTx) WHERE otherTx.timestamp < maxdate and otherTx.timestamp > mindate RETURN term.tid AS terminal,mindate,maxdate, 100 * ct / COUNT(DISTINCT otherTx.cardno) AS impact, (maxdate - mindate)/(24*3600000) as timewindow ORDER BY impact DESC, timewindow DESC Query: Fraud origination at terminal level
  26. 26. MATCH (term:Terminal)<-[:IN_TERMINAL]-(t)-[n:NEXT*]->(:FraudTx) WITH term , count(distinct t.cardno) as ct, min(t.timestamp) as mindate, max(t.timestamp) as maxdate WHERE ct > 1 MATCH (term)<-[:IN_TERMINAL]-(otherTx) WHERE otherTx.timestamp < maxdate and otherTx.timestamp > mindate RETURN term.tid AS terminal,mindate,maxdate, 100 * ct / COUNT(DISTINCT otherTx.cardno) AS impact, (maxdate - mindate)/(24*3600000) as timewindow ORDER BY impact DESC, timewindow DESC Query: Fraud origination at terminal level
  27. 27. Query: Fraud origination at terminal level
  28. 28. WITH { tid : '2373743-7', from: 1487340089000, to: 1488039852000 } AS compTerm MATCH (term:Terminal { tid: compTerm.tid} )<-[:IN_TERMINAL]-(t) WHERE NOT (t)-[:NEXT*]->(:FraudTx) AND t.timestamp > compTerm.from AND t.timestamp < compTerm.to RETURN distinct t.cardno AS cardAtRisk Query: Proactive prevention
  29. 29. WITH { tid : '2373743-7', from: 1487340089000, to: 1488039852000 } AS compTerm MATCH (term:Terminal { tid: compTerm.tid} )<-[:IN_TERMINAL]-(t) WHERE NOT (t)-[:NEXT*]->(:FraudTx) AND t.timestamp > compTerm.from AND t.timestamp < compTerm.to RETURN distinct t.cardno AS cardAtRisk Query: Proactive prevention
  30. 30. WITH { tid : '2373743-7', from: 1487340089000, to: 1488039852000 } AS compTerm MATCH (term:Terminal { tid: compTerm.tid} )<-[:IN_TERMINAL]-(t) WHERE NOT (t)-[:NEXT*]->(:FraudTx) AND t.timestamp > compTerm.from AND t.timestamp < compTerm.to RETURN distinct t.cardno AS cardAtRisk Query: Proactive prevention
  31. 31. Query: Proactive prevention
  32. 32. Why graph native matters DB#1 1027910 nodes 4017217 relationships 10044420 properties DB#2 509451186 nodes 1008977685 relationships 3551517114 properties Fraud origination at terminal level 93ms 104 ms Fraud origination at merchant level 102ms 116 ms Proactive prevention 11ms 12 ms
  33. 33. Example 1: Credit card fraud origination and assessment of potential impact
  34. 34. Example 2: Referral program fraud
  35. 35. The flatmates <-[:INVITES]------ <-[:INVITES]------------ -----[:TRANSFER{amount:200}]-> <-[:INVITES]- -------------[:TRANSFER{amount:200}]-> -[:TRANSFER{amount:200}]->
  36. 36. timestamp ,from,to ,amnt ,transferid 1492194035,3316,3606,33.52,f4d21fed-a307-4 1493759810,2693,3886,1655.53,8d060469-f363 1493889115,2229,3557,2725.36,f32b20de-f227 1493946497,3877,2343,672.9,064b98fb-5395-4 1493413944,2360,3358,78.68,d87308f4-508b-4 1491524249,3472,3490,1894.58,3e9bdf77-06be 1492912151,3576,3196,3335.02,d3a50a83-329a 1491846100,3717,2269,3891.62,3fc0f2d6-57c4 1492268780,2656,3527,1809.7,cbc16b4f-b95e- 1493420085,2873,3749,2960.73,4fbf48b8-7501 1492236572,2223,3120,2973.38,1e5b95e7-4e86 1492735617,2318,2820,36.04,c07bc1cd-8970-4
  37. 37. MATCH p = (u:User)-[i:INVITES]->(x)-[t:TRANSFER]->(u) WHERE t.timestamp - i.timestamp < 15*24*3600000 AND t.amount < 210 AND t.amount > 199 AND size((x)-[:TRANSFER]-())=1 RETURN p
  38. 38. MATCH p = (u:User)-[i:INVITES]->(x)-[t:TRANSFER]->(u) WHERE t.timestamp - i.timestamp < 15*24*3600000 AND t.amount < 210 AND t.amount > 199 AND size((x)-[:TRANSFER]-())=1 RETURN p
  39. 39. MATCH p = (u:User)-[i:INVITES]->(x)-[t:TRANSFER]->(u) WHERE t.timestamp - i.timestamp < 15*24*3600000 AND t.amount < 210 AND t.amount > 199 AND size((x)-[:TRANSFER]-())=1 RETURN p
  40. 40. Fraudsters got more and more sophisticated... <-[:INVITES]-- --[:INVITES]-> ---[:INVITES]-> -[:TRANSFER]-> -[:TRANSFER]-> <-[:TRANSFER]---
  41. 41. But cypher beat them all! MATCH p = (u:User)-[i:INVITES]->(x)-[t:TRANSFER*3..]->(u) WHERE all(r IN relationships(p) WHERE type(r) <>'TRANSFER' OR (r.timestamp - i.timestamp < 15*24*3600000 AND r.amount < 210 AND r.amount > 199)) AND all(n IN nodes(p) WHERE n=u or size((n)-[:TRANSFER]->())=1) RETURN p
  42. 42. But cypher beat them all! MATCH p = (u:User)-[i:INVITES]->(x)-[t:TRANSFER*3..]->(u) WHERE all(r IN relationships(p) WHERE type(r) <>'TRANSFER' OR (r.timestamp - i.timestamp < 15*24*3600000 AND r.amount < 210 AND r.amount > 199)) AND all(n IN nodes(p) WHERE n=u or size((n)-[:TRANSFER]->())=1) RETURN p and *3.. detects chains of any length!
  43. 43. But cypher beat them all! MATCH p = (u:User)-[i:INVITES]->(x)-[t:TRANSFER*3..]->(u) WHERE all(r IN relationships(p) WHERE type(r) <>'TRANSFER' OR (r.timestamp - i.timestamp < 15*24*3600000 AND r.amount < 210 AND r.amount > 199)) AND all(n IN nodes(p) WHERE n=u or size((n)-[:TRANSFER]->())=1) RETURN p
  44. 44. I could go on with more variants the pattern... <-[:INVITES]- --[:INVITES]->---[:INVITES]-> -[:TRANSFER]-> -[:TRANSFER]-> -[:TRANSFER]-> MATCH p = (u:User)-[i:INVITES]->(x)-[t:TRANSFER*3..]->()
  45. 45. Example 2: Referral program fraud
  46. 46. Three takeaways Graph thinking Graph native matters Graphs rock! Enjoy the rest of the day!
  47. 47. Kiitos!

×