SlideShare a Scribd company logo
Decision Trees in Neo4j
Build dynamic expert systems and rules engines.
github.com/maxdemarzi
About 200 public repositories
Max De Marzi
Neo4j Field Engineer
About
Me !
01
02
03
04
maxdemarzi.com
@maxdemarzi
Let’s start with a Sign
Decision Trees in Neo4j
Decision Trees in Neo4j
Rule for Getting In
• Anyone over 21 years old gets in.
• On some nights, women 18 years or older get in.
• On some nights, men 18 years or older get in.
• The last two change dynamically.
Represent in a Graph
Decision Trees in Neo4j
Rule Node
• expression (String):
• (age >= 18) && gender.equals(“female”)
• parameter_names(String):
• age, gender
• parameter_types(String):
• Int, String
There was a time…
BEFORE
Decision Trees in Neo4j
When the Traversal API ruled supreme
https://maxdemarzi.com/2015/09/04/flight-search-with-the-neo4j-traversal-api/
Learn more… or read the docs
The Stored Procedure
@Procedure(name = "com.maxdemarzi.traverse.decision_tree", mode = Mode.READ)
@Description("CALL com.maxdemarzi.traverse.decision_tree(tree, facts)")
public Stream<PathResult> traverseDecisionTree(
@Name("tree") String id,
@Name("facts") Map<String, String> facts){
// Which Decision Tree are we interested in?
Node tree = db.findNode(Labels.Tree, "id", id);
if ( tree != null) {
// Find the paths by traversing this graph and the facts given
return decisionPath(tree, facts);
}
return null;
}
Tree Facts
private Stream<PathResult> decisionPath(Node tree, 

Map<String, String> facts) {
TraversalDescription myTraversal =
db.traversalDescription()
.depthFirst()
.expand(new DecisionTreeExpander(facts))
.evaluator(decisionTreeEvaluator);
return myTraversal
.traverse(tree)
.stream()
.map(PathResult::new);
}
Build a Traversal Description
Decision Trees in Neo4j
public class DecisionTreeEvaluator implements PathEvaluator {
@Override
public Evaluation evaluate(Path path, BranchState branchState) {
// If we get to an Answer stop traversing, we found a valid path.
if (path.endNode().hasLabel(Labels.Answer)) {
return Evaluation.INCLUDE_AND_PRUNE;
} else {
// If not, continue down this path 

// to see if there is anything else to find.
return Evaluation.EXCLUDE_AND_CONTINUE;
}
}
Build a Path Evaluator
Decision Trees in Neo4j
public class DecisionTreeExpander implements PathExpander {
private Map<String, String> facts;
private ExpressionEvaluator ee = new ExpressionEvaluator();
public DecisionTreeExpander(Map<String, String> facts) {
this.facts = facts;
ee.setExpressionType(boolean.class);
}
Build a Path Expander
@Override
public Iterable<Relationship> expand(Path path, BranchState branchState) {
// If we get to an Answer stop traversing, we found a valid path.
if (path.endNode().hasLabel(Labels.Answer)) {
return Collections.emptyList();
}
// If we have Rules to evaluate, go do that.
if (path.endNode()
.hasRelationship(Direction.OUTGOING, RelationshipTypes.HAS)) {
return path.endNode()
.getRelationships(Direction.OUTGOING, RelationshipTypes.HAS);
}
The expand method
if (path.endNode().hasLabel(Labels.Rule)) {
try {
if (isTrue(path.endNode())) {
return path.endNode()
.getRelationships(Direction.OUTGOING,
RelationshipTypes.IS_TRUE);
} else {
return path.endNode()
.getRelationships(Direction.OUTGOING,
RelationshipTypes.IS_FALSE);
}
} catch (Exception e) {
// Could not continue this way!
return Collections.emptyList();
}
}
The expand method (cont.)
Decision Trees in Neo4j
boolean isTrue(Node rule) throws Exception {
Map<String, Object> ruleProperties = rule.getAllProperties();
String[] parameterNames =
Magic.explode((String) ruleProperties
.get("parameter_names"));
Class<?>[] parameterTypes =
Magic.stringToTypes((String) ruleProperties
.get("parameter_types"));
The isTrue method
Object[] arguments = new Object[parameterNames.length];
for (int j = 0; j < parameterNames.length; ++j) {
arguments[j] = Magic.createObject(parameterTypes[j],
facts.get(parameterNames[j]));
}
ee.setParameters(parameterNames, parameterTypes);
ee.cook((String)ruleProperties.get("expression"));
return (boolean) ee.evaluate(arguments);
The isTrue method (cont.)
Running it
Decision Trees in Neo4j
Decision Trees in Neo4j
CREATE (tree:Tree { id: 'bar entrance' })
CREATE (over21_rule:Rule { parameter_names: 'age',
parameter_types:'int',
expression:'age >= 21' })
CREATE (gender_rule:Rule { parameter_names: 'age,gender',
parameter_types:'int,String',
expression:'(age >= 18) && gender.equals("female")' })
CREATE (answer_yes:Answer { id: 'yes'})
CREATE (answer_no:Answer { id: 'no'})
CREATE (tree)-[:HAS]->(over21_rule)
CREATE (over21_rule)-[:IS_TRUE]->(answer_yes)
CREATE (over21_rule)-[:IS_FALSE]->(gender_rule)
CREATE (gender_rule)-[:IS_TRUE]->(answer_yes)
CREATE (gender_rule)-[:IS_FALSE]->(answer_no)
Build the Tree
Decision Trees in Neo4j
CALL com.maxdemarzi.traverse.decision_tree(

‘bar entrance', {gender:'male', age:'20'})
YIELD path
RETURN path;
Check the Facts
Male, 20 years old?
Decision Trees in Neo4j
It’s alright…
CALL com.maxdemarzi.traverse.decision_tree(

‘bar entrance', {gender:'female', age:’19'})
YIELD path
RETURN path;
Female, 19 years old?
Check the Facts
Decision Trees in Neo4j
OMG…
Decision Trees in Neo4j
Learn More…
https://maxdemarzi.com/2018/01/14/dynamic-rule-based-decision-trees-in-neo4j/
Details:
What about multiple Options?
https://maxdemarzi.com/2018/01/26/dynamic-rule-based-decision-trees-in-neo4j-part-2/
There is a Part 2
Decision Trees in Neo4j
Decision Streams
• Paper: 

https://arxiv.org/pdf/1704.07657.pdf
• Authors:

Dmitry Ignatov and Andrey Ignatov
• Implementation: 

https://github.com/aiff22/Decision-Stream
Decision Trees in Neo4j
Thank you!

More Related Content

PPTX
Approval testing from basic to advanced
PDF
Developing Applications with MySQL and Java for beginners
PDF
functional groovy
PDF
awesome groovy
PPT
Introduction To Groovy
PDF
JS OO and Closures
PDF
groovy databases
PDF
concurrency with GPars
Approval testing from basic to advanced
Developing Applications with MySQL and Java for beginners
functional groovy
awesome groovy
Introduction To Groovy
JS OO and Closures
groovy databases
concurrency with GPars

What's hot (6)

PPTX
Java and XML Schema
ODP
Scala introduction
PDF
dotSwift 2016 : Beyond Crusty - Real-World Protocols
PPTX
Java Hello World Program
PDF
webScrapingFunctions
ODP
GPars (Groovy Parallel Systems)
Java and XML Schema
Scala introduction
dotSwift 2016 : Beyond Crusty - Real-World Protocols
Java Hello World Program
webScrapingFunctions
GPars (Groovy Parallel Systems)
Ad

Similar to Decision Trees in Neo4j (20)

PDF
MWLUG Session- AD112 - Take a Trip Into the Forest - A Java Primer on Maps, ...
PDF
More Stored Procedures and MUMPS for DivConq
PDF
Google Guava for cleaner code
PPTX
Binary Studio Academy PRO: ANTLR course by Alexander Vasiltsov (lesson 4)
PPTX
Taxonomy of Scala
PDF
APPLICATION TO DOCUMENT ALL THE DETAILS OF JAVA CLASSES OF A PROJECT AT ONCE...
PDF
Take a Trip Into the Forest: A Java Primer on Maps, Trees, and Collections
PPT
Building Single-Page Web Appplications in dart - Devoxx France 2013
PDF
Scala - en bedre og mere effektiv Java?
PPT
Explain Classes and methods in java (ch04).ppt
PDF
Scala in Places API
PDF
SAX, DOM & JDOM parsers for beginners
PDF
RESTful Web Services with Jersey
PDF
Scala - en bedre Java?
PDF
Querydsl fin jug - june 2012
PPT
Simple API for XML
PDF
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
PDF
C++ 11 usage experience
PPTX
What is new in Java 8
PPTX
Java 8 revealed
MWLUG Session- AD112 - Take a Trip Into the Forest - A Java Primer on Maps, ...
More Stored Procedures and MUMPS for DivConq
Google Guava for cleaner code
Binary Studio Academy PRO: ANTLR course by Alexander Vasiltsov (lesson 4)
Taxonomy of Scala
APPLICATION TO DOCUMENT ALL THE DETAILS OF JAVA CLASSES OF A PROJECT AT ONCE...
Take a Trip Into the Forest: A Java Primer on Maps, Trees, and Collections
Building Single-Page Web Appplications in dart - Devoxx France 2013
Scala - en bedre og mere effektiv Java?
Explain Classes and methods in java (ch04).ppt
Scala in Places API
SAX, DOM & JDOM parsers for beginners
RESTful Web Services with Jersey
Scala - en bedre Java?
Querydsl fin jug - june 2012
Simple API for XML
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
C++ 11 usage experience
What is new in Java 8
Java 8 revealed
Ad

More from Max De Marzi (20)

PDF
AI, Tariffs and Supply Chains in Knowledge Graphs
PDF
DataDay 2023 Presentation
PDF
DataDay 2023 Presentation - Notes
PPTX
Developer Intro Deck-PowerPoint - Download for Speaker Notes
PDF
Outrageous Ideas for Graph Databases
PDF
Neo4j Training Cypher
PDF
Neo4j Training Modeling
PPTX
Neo4j Training Introduction
PDF
Detenga el fraude complejo con Neo4j
PDF
Data Modeling Tricks for Neo4j
PDF
Fraud Detection and Neo4j
PDF
Detecion de Fraude con Neo4j
PDF
Neo4j Data Science Presentation
PDF
Neo4j Stored Procedure Training Part 2
PDF
Neo4j Stored Procedure Training Part 1
PDF
Neo4j y Fraude Spanish
PDF
Data modeling with neo4j tutorial
PDF
Neo4j Fundamentals
PDF
Neo4j Presentation
PDF
Fraud Detection Class Slides
AI, Tariffs and Supply Chains in Knowledge Graphs
DataDay 2023 Presentation
DataDay 2023 Presentation - Notes
Developer Intro Deck-PowerPoint - Download for Speaker Notes
Outrageous Ideas for Graph Databases
Neo4j Training Cypher
Neo4j Training Modeling
Neo4j Training Introduction
Detenga el fraude complejo con Neo4j
Data Modeling Tricks for Neo4j
Fraud Detection and Neo4j
Detecion de Fraude con Neo4j
Neo4j Data Science Presentation
Neo4j Stored Procedure Training Part 2
Neo4j Stored Procedure Training Part 1
Neo4j y Fraude Spanish
Data modeling with neo4j tutorial
Neo4j Fundamentals
Neo4j Presentation
Fraud Detection Class Slides

Recently uploaded (20)

PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Understanding Forklifts - TECH EHS Solution
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
Introduction to Artificial Intelligence
PDF
Digital Systems & Binary Numbers (comprehensive )
PDF
medical staffing services at VALiNTRY
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
PPTX
history of c programming in notes for students .pptx
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Understanding Forklifts - TECH EHS Solution
Design an Analysis of Algorithms II-SECS-1021-03
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Operating system designcfffgfgggggggvggggggggg
Introduction to Artificial Intelligence
Digital Systems & Binary Numbers (comprehensive )
medical staffing services at VALiNTRY
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
VVF-Customer-Presentation2025-Ver1.9.pptx
Odoo Companies in India – Driving Business Transformation.pdf
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Which alternative to Crystal Reports is best for small or large businesses.pdf
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Design an Analysis of Algorithms I-SECS-1021-03
How to Migrate SBCGlobal Email to Yahoo Easily
Embracing Complexity in Serverless! GOTO Serverless Bengaluru
history of c programming in notes for students .pptx

Decision Trees in Neo4j

  • 1. Decision Trees in Neo4j Build dynamic expert systems and rules engines.
  • 2. github.com/maxdemarzi About 200 public repositories Max De Marzi Neo4j Field Engineer About Me ! 01 02 03 04 maxdemarzi.com @maxdemarzi
  • 6. Rule for Getting In • Anyone over 21 years old gets in. • On some nights, women 18 years or older get in. • On some nights, men 18 years or older get in. • The last two change dynamically.
  • 9. Rule Node • expression (String): • (age >= 18) && gender.equals(“female”) • parameter_names(String): • age, gender • parameter_types(String): • Int, String
  • 10. There was a time… BEFORE
  • 12. When the Traversal API ruled supreme
  • 15. @Procedure(name = "com.maxdemarzi.traverse.decision_tree", mode = Mode.READ) @Description("CALL com.maxdemarzi.traverse.decision_tree(tree, facts)") public Stream<PathResult> traverseDecisionTree( @Name("tree") String id, @Name("facts") Map<String, String> facts){ // Which Decision Tree are we interested in? Node tree = db.findNode(Labels.Tree, "id", id); if ( tree != null) { // Find the paths by traversing this graph and the facts given return decisionPath(tree, facts); } return null; } Tree Facts
  • 16. private Stream<PathResult> decisionPath(Node tree, 
 Map<String, String> facts) { TraversalDescription myTraversal = db.traversalDescription() .depthFirst() .expand(new DecisionTreeExpander(facts)) .evaluator(decisionTreeEvaluator); return myTraversal .traverse(tree) .stream() .map(PathResult::new); } Build a Traversal Description
  • 18. public class DecisionTreeEvaluator implements PathEvaluator { @Override public Evaluation evaluate(Path path, BranchState branchState) { // If we get to an Answer stop traversing, we found a valid path. if (path.endNode().hasLabel(Labels.Answer)) { return Evaluation.INCLUDE_AND_PRUNE; } else { // If not, continue down this path 
 // to see if there is anything else to find. return Evaluation.EXCLUDE_AND_CONTINUE; } } Build a Path Evaluator
  • 20. public class DecisionTreeExpander implements PathExpander { private Map<String, String> facts; private ExpressionEvaluator ee = new ExpressionEvaluator(); public DecisionTreeExpander(Map<String, String> facts) { this.facts = facts; ee.setExpressionType(boolean.class); } Build a Path Expander
  • 21. @Override public Iterable<Relationship> expand(Path path, BranchState branchState) { // If we get to an Answer stop traversing, we found a valid path. if (path.endNode().hasLabel(Labels.Answer)) { return Collections.emptyList(); } // If we have Rules to evaluate, go do that. if (path.endNode() .hasRelationship(Direction.OUTGOING, RelationshipTypes.HAS)) { return path.endNode() .getRelationships(Direction.OUTGOING, RelationshipTypes.HAS); } The expand method
  • 22. if (path.endNode().hasLabel(Labels.Rule)) { try { if (isTrue(path.endNode())) { return path.endNode() .getRelationships(Direction.OUTGOING, RelationshipTypes.IS_TRUE); } else { return path.endNode() .getRelationships(Direction.OUTGOING, RelationshipTypes.IS_FALSE); } } catch (Exception e) { // Could not continue this way! return Collections.emptyList(); } } The expand method (cont.)
  • 24. boolean isTrue(Node rule) throws Exception { Map<String, Object> ruleProperties = rule.getAllProperties(); String[] parameterNames = Magic.explode((String) ruleProperties .get("parameter_names")); Class<?>[] parameterTypes = Magic.stringToTypes((String) ruleProperties .get("parameter_types")); The isTrue method
  • 25. Object[] arguments = new Object[parameterNames.length]; for (int j = 0; j < parameterNames.length; ++j) { arguments[j] = Magic.createObject(parameterTypes[j], facts.get(parameterNames[j])); } ee.setParameters(parameterNames, parameterTypes); ee.cook((String)ruleProperties.get("expression")); return (boolean) ee.evaluate(arguments); The isTrue method (cont.)
  • 29. CREATE (tree:Tree { id: 'bar entrance' }) CREATE (over21_rule:Rule { parameter_names: 'age', parameter_types:'int', expression:'age >= 21' }) CREATE (gender_rule:Rule { parameter_names: 'age,gender', parameter_types:'int,String', expression:'(age >= 18) && gender.equals("female")' }) CREATE (answer_yes:Answer { id: 'yes'}) CREATE (answer_no:Answer { id: 'no'}) CREATE (tree)-[:HAS]->(over21_rule) CREATE (over21_rule)-[:IS_TRUE]->(answer_yes) CREATE (over21_rule)-[:IS_FALSE]->(gender_rule) CREATE (gender_rule)-[:IS_TRUE]->(answer_yes) CREATE (gender_rule)-[:IS_FALSE]->(answer_no) Build the Tree
  • 31. CALL com.maxdemarzi.traverse.decision_tree(
 ‘bar entrance', {gender:'male', age:'20'}) YIELD path RETURN path; Check the Facts Male, 20 years old?
  • 34. CALL com.maxdemarzi.traverse.decision_tree(
 ‘bar entrance', {gender:'female', age:’19'}) YIELD path RETURN path; Female, 19 years old? Check the Facts
  • 43. Decision Streams • Paper: 
 https://arxiv.org/pdf/1704.07657.pdf • Authors:
 Dmitry Ignatov and Andrey Ignatov • Implementation: 
 https://github.com/aiff22/Decision-Stream