Dear neo4j developer
I have a question, I want to use Neo4j for Heterogeneous nodes link prediction.
There are 2 types of node labels, and I need to predict the connections between these 2 types of nodes.
Do you have any actual code examples for this?"
I tested using the example from Training the pipeline - Neo4j Graph Data Science.
Then I used my own data (code as follows:), and made many changes (e.g. sourceNodeLabel: 'Person', targetNodeLabel: 'Product', targetRelationshipType: 'BUY').
However, the results seemed unreasonable, with all probabilities being 0.4999.
Could you please advise how I should modify the code? Where did I go wrong? Are there any other examples I can refer to? Thank you.
code: (below)
CREATE
(alice:Person {name: 'Alice', age: 38, gender:1}),
(michael:Person {name: 'Michael', age: 67, gender:0}),
(karin:Person {name: 'Karin', age: 30, gender:1}),
(chris:Person {name: 'Chris', age: 52, gender:0}),
(will:Person {name: 'Will', age: 18, gender:0}),
(mark:Person {name: 'Mark', age: 20, gender:0}),
(milk:Product {name: 'milk', price:80}),
(apple:Product {name: 'apple', price:25}),
(orange:Product {name: 'orange', price:35}),
(piapple:Product {name: 'piapple', price:65}),
(watermelon:Product {name: ' watermelon', price:45}),
(cantaloupe:Product {name: 'cantaloupe', price:55}),
(notebook:Product {name: 'notebook', price:25000}),
(tv:Product {name: 'TV', price:19999}),
(aircon:Product {name: 'aircondition', price:29000}),
(shoe_air:Product {name: 'shoe_air', price:5000}),
(runshoes:Product {name: 'runshoes', price:1999}),
(sportshoes:Product {name: 'sportshoes', price:3900}),
(goodshoes:Product {name: 'goodshoes', price:7900}),
(underwear:Product {name: 'Underwear', price:390}),
(pants:Product {name: 'Pants', price:499}),
(jen:Product {name: 'Jen', price:600}),
(fruit:fruit {name: 'fruit'}),
(ele:ele {name: 'ele'}),
(shoe:shoe {name: 'shoe'}),
(clothe:clothe {name: 'clothe'}),
(milk)-[:BELONG]->(fruit),
(apple)-[:BELONG]->(fruit),
(orange)-[:BELONG]->(fruit),
(piapple)-[:BELONG]->(fruit),
(watermelon)-[:BELONG]->(fruit),
(cantaloupe)-[:BELONG]->(fruit),
(notebook)-[:BELONG]->(ele),
(tv)-[:BELONG]->(ele),
(aircon)-[:BELONG]->(ele),
(shoe_air)-[:BELONG]->(shoe),
(runshoes)-[:BELONG]->(shoe),
(sportshoes)-[:BELONG]->(shoe),
(goodshoes)-[:BELONG]->(shoe),
(underwear)-[:BELONG]->(clothe),
(pants)-[:BELONG]->(clothe),
(jen)-[:BELONG]->(clothe),
(alice)-[:BUY]->(milk),
(alice)-[:BUY]->(apple),
(alice)-[:BUY]->(orange),
(alice)-[:BUY]->(piapple),
(michael)-[:BUY]->(apple),
(michael)-[:BUY]->(orange),
(michael)-[:BUY]->(notebook),
(michael)-[:BUY]->(shoe_air),
(karin)-[:BUY]->(milk),
(karin)-[:BUY]->(pants),
(karin)-[:BUY]->(jen),
(karin)-[:BUY]->(underwear),
(chris)-[:BUY]->(sportshoes),
(chris)-[:BUY]->(runshoes),
(chris)-[:BUY]->(goodshoes),
(will)-[:BUY]->(aircon),
(will)-[:BUY]->(tv),
(will)-[:BUY]->(notebook),
(mark)-[:BUY]->(watermelon),
(mark)-[:BUY]->(cantaloupe),
(alice)-[:FRIEND]->(michael),
(michael)-[:FRIEND]->(will),
(michael)-[:FRIEND]->(mark),
(alice)-[:FRIEND]->(karin),
(will)-[:FRIEND]->(mark),
(mark)-[:FRIEND]->(chris),
(chris)-[:FRIEND]->(alice),
(will)-[:FRIEND]->(karin)
CALL gds.graph.project(
'fullGraph',
{
Person:
{
properties:
{
age: {defaultValue: 1},
price: {defaultValue: 1}
}
},
Product:
{
properties:
{
age: {defaultValue: 1},
price: {defaultValue: 1}
}
}
},
{
BUY: {
orientation: 'UNDIRECTED'
},
FRIEND: {},
BELONG: {}
}
)
CALL gds.beta.pipeline.linkPrediction.create('pipe-with-context')
CALL gds.beta.pipeline.linkPrediction.addNodeProperty('pipe-with-context', 'fastRP', {
mutateProperty: 'embedding',
embeddingDimension: 256,
randomSeed: 42,
contextRelationshipTypes: ['FRIEND', 'BELONG']
})
CALL gds.beta.pipeline.linkPrediction.addFeature('pipe-with-context', 'hadamard', {
nodeProperties: ['embedding', 'age', 'price']
})
CALL gds.beta.pipeline.linkPrediction.configureSplit('pipe-with-context', {
testFraction: 0.25,
trainFraction: 0.6,
validationFolds: 3
})
CALL gds.alpha.pipeline.linkPrediction.addMLP('pipe-with-context',
{hiddenLayerSizes: [4, 2], penalty: 1, patience: 2})
CALL gds.beta.pipeline.linkPrediction.train('fullGraph', {
pipeline: 'pipe-with-context',
modelName: 'lp-pipeline-model-filtered',
metrics: ['AUCPR', 'OUT_OF_BAG_ERROR'],
sourceNodeLabel: 'Person',
targetNodeLabel: 'Product',
targetRelationshipType: 'BUY',
randomSeed: 12
}) YIELD modelInfo, modelSelectionStats
RETURN
modelInfo.bestParameters AS winningModel,
modelInfo.metrics.AUCPR.train.avg AS avgTrainScore,
modelInfo.metrics.AUCPR.outerTrain AS outerTrainScore,
modelInfo.metrics.AUCPR.test AS testScore,
[cand IN modelSelectionStats.modelCandidates | cand.metrics.AUCPR.validation.avg] AS validationScores
CALL gds.beta.pipeline.linkPrediction.predict.stream('fullGraph', {
modelName: 'lp-pipeline-model-filtered',
topN: 50,
threshold: 0
})
YIELD node1, node2, probability
RETURN gds.util.asNode(node1).name AS Person, gds.util.asNode(node2).name AS Product, probability
ORDER BY Product
Result : (below)
╒═══════════╤══════════════╤══════════════════╕
│Person │Product │probability │
╞═══════════╪══════════════╪══════════════════╡
│"Alice" │" watermelon" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Alice" │"cantaloupe" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Alice" │"TV" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Alice" │"shoe_air" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Alice" │"sportshoes" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Alice" │"runshoes" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Alice" │"aircondition"│0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Alice" │"notebook" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"milk" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"cantaloupe" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"TV" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"shoe_air" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"aircondition"│0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"notebook" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │" watermelon" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"piapple" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"orange" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Chris" │"apple" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"piapple" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"cantaloupe" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"TV" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"shoe_air" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"sportshoes" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"runshoes" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"aircondition"│0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"notebook" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │" watermelon" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"orange" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Karin" │"apple" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"milk" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"orange" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"TV" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"shoe_air" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"runshoes" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"sportshoes" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"aircondition"│0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"notebook" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"piapple" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Mark" │"apple" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Pants" │"Alice" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Pants" │"Michael" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Pants" │"Will" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Pants" │"Mark" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Pants" │"Chris" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Underwear"│"Alice" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Underwear"│"Michael" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Underwear"│"Mark" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Underwear"│"Will" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Underwear"│"Chris" │0.4999999999999998│
├───────────┼──────────────┼──────────────────┤
│"Will" │"milk" │0.4999999999999998│
└───────────┴──────────────┴──────────────────┘
Neo4j Desktop-1.5.7
Version 5.18.0Preformatted text