Introduzione ai graph embeddings

Un singolo account, considerato isolatamente, fornisce poche informazioni. Osservando invece a chi invia denaro, chi a sua volta riceve denaro, e così via, si ottiene un quadro ricco di connessioni. Questo è il principio alla base dei graph embeddings: comprimere la struttura di un nodo e del suo contesto in un vettore numerico. I nodi con ambienti simili ottengono vettori simili. Nella documentazione Neo4j questi vettori sono chiamati node embeddings, perché ogni nodo riceve il proprio spazio vettoriale.

Negli ultimi anni gli embeddings sono diventati il caso d’uso a più rapida crescita per Neo4j Graph Data Science (GDS). Quando ogni nodo è rappresentato da un vettore, problemi complessi si trasformano in compiti di machine learning tradizionali: un team antifrode può segnalare account simili a noti frodatori, un retailer può raccomandare prodotti a clienti con profili analoghi, un analista può segmentare la clientela in base alle connessioni e un data scientist può inserire i vettori in modelli standard per predire il churn.

Da data scientist a sviluppatore: semplificare il flusso

In passato la creazione di embeddings richiedeva competenze avanzate: scegliere il modello più adatto, configurare parametri, comprendere il significato di ciascuna impostazione. Molti team hanno scalato questa “montagna di concetti” testando modelli e affinando configurazioni finché i risultati non erano soddisfacenti. Con le text embeddings il processo è più lineare: una singola chiamata restituisce i vettori, senza bisogno di conoscere i dettagli interni. Neo4j intende offrire lo stesso livello di semplicità anche per i graph embeddings.

Una sola riga di codice

Con la versione 2.2 o successiva del client Python GDS, è disponibile in anteprima una nuova Embeddings API per Aura Graph Analytics. La chiamata completa è:

gds.embedding.create(G)

dove G è il grafo caricato in una sessione Aura. Dietro le quinte, l’algoritmo FastRP genera gli embeddings usando impostazioni predefinite ottimizzate per la maggior parte dei casi. L’utente può quindi concentrarsi sull’utilizzo dei vettori, non sulla loro produzione.

Personalizzazione e controllo

Quando serve più fine‑tuning, l’API permette di regolare diversi parametri:

    • dimensione dell’embedding (embedding_dimension)
    • nome della proprietà in cui salvare il vettore (mutate_property)
    • selezione di etichette di nodo o tipologie di relazione da includere
    • seed casuale per risultati riproducibili (random_seed)

Esempio con impostazioni avanzate:

gds.embedding.create(

G,

embedding_dimension=256,

mutateproperty="embedding256",

random_seed=42

)

Se la proprietà indicata esiste già, la chiamata fallisce, evitando sovrascritture accidentali. Durante la sperimentazione è consigliabile utilizzare nomi diversi per ciascun set di embeddings, così da poter confrontare i risultati. In produzione, è possibile rimuovere la proprietà esistente con gds.graph.nodeproperties.drop impostando failif_missing=False per garantire la sicurezza dell’operazione.

Cosa accade al grafo

Gli embeddings vengono aggiunti al grafo in memoria come nuova proprietà del nodo, denominata di default embedding. Nessun dato viene scritto sul database a meno che l’utente non lo richieda esplicitamente. Da lì, i vettori possono essere esportati in pandas, passati a ulteriori algoritmi (k‑NN, k‑means) o scritti nuovamente nel database per usi successivi.

Quando i default non bastano: GraphSAGE

FastRP cattura la posizione del nodo nella topologia globale, ma ignora le proprietà dei nodi. Se le informazioni di business, come un risk_class numerico o un vettore di features, sono rilevanti, è necessario un approccio più sofisticato. Qui entra in gioco gds.embedding.train, che addestra un modello GraphSAGE combinando proprietà dei nodi e classi note.

Esempio di proiezione con proprietà aggiuntive:

G, result = gds.graph.project.native(

"labeled-transfers",

["Account"],

["TRANSFERRED_TO"],

nodeproperties=["riskclass", "features"]

)

Successivamente, si avvia l’addestramento specificando l’etichetta target, la proprietà target e le proprietà di input:

gds.embedding.train(

G,

model_name="account-risk-encoder",

target_label="Account",

targetproperty="riskclass",

feature_properties=["features"]

)

Il modello risultante può essere riutilizzato nella chiamata gds.embedding.create passando il nome del modello e le proprietà da considerare:

gds.embedding.create(

G,

graph_encoder="account-risk-encoder",

mutateproperty="embeddingtuned",

feature_properties=["features"]

)

È importante valutare le performance su nodi non presenti nel set di training, per evitare bias.

Distribuzione e sperimentazione rapida

Aura Graph Analytics è disponibile anche nel tier gratuito di AuraDB, permettendo di testare le API senza costi. I dati non devono necessariamente risiedere in Neo4j; è possibile caricare nodi e relazioni da data warehouse, Databricks o CSV in DataFrame pandas e trasformarli in un grafo con gds.graph.construct.

La documentazione dell’Embeddings API offre un riferimento completo dei parametri e un quick‑start che utilizza il grafo di citazioni Cora, incluso nel client Python GDS. Entrambi gli endpoint sono attualmente in preview, quindi soggetti a modifiche basate sul feedback degli utenti.

Prospettive future

Questa prima versione rappresenta solo l’inizio. Neo4j prevede di arricchire l’API con nuove funzionalità, tra cui:

    • supporto per algoritmi di embeddings più avanzati (ad esempio, DeepWalk, Node2Vec)
    • integrazione nativa con modelli di linguaggio di grandi dimensioni per combinare testo e grafo
    • pipeline di training automatizzate per scenari multi‑task

Nel frattempo, gli sviluppatori possono già sfruttare una potente capacità di trasformare la struttura di rete in vettori pronti per il machine learning con una sola linea di codice, accelerando la sperimentazione e riducendo le barriere all’adozione dell’intelligenza artificiale basata su grafi.