{"slug": "graph-embeddings-one-line-of-code-away", "title": "Graph Embeddings, One Line of Code Away", "summary": "Neo4j released a preview Embeddings API in version 2.2 or later of its GDS Python client for Aura Graph Analytics, letting users generate a vector for every node with the single call gds.embedding.create(G). The API runs the FastRP algorithm with pre-chosen defaults, stores embeddings as a node property named embedding in the in-memory graph without writing to the database, and exposes settings for embedding size, node labels, relationship types, and a random_seed for reproducibility. Neo4j said embeddings have been the fastest-growing use case for its Graph Data Science library.", "body_md": "# Graph Embeddings, One Line of Code Away\n\nSenior Product Manager, Graph Analytics, Neo4j\n\n8 min read\n\nA single account on its own tells you very little. But look at who it sends money to, who *those* accounts send money to, and suddenly you have got a lot to work with.\n\nThat’s the idea behind graph embeddings: take a node and everything around it, and compress that graph structure into a vector. Nodes with similar surroundings end up with similar vectors. You will also see these called node embeddings, the name we use in the docs, because every node gets a vector of its own.\n\nOver the last few years, embeddings have been the fastest-growing use case for [Neo4j Graph Data Science](https://neo4j.com/product/graph-data-science/) (GDS), our graph analytics and machine learning library, and we are not surprised. Once every node is a vector, a lot of hard problems turn into ordinary ones: \n\n- A fraud team can flag accounts that look like known fraudsters.\n- A retailer can recommend what similar customers bought.\n- An analyst can segment customers by how they connect to everyone else, and a data scientist can feed the vectors to a standard model to predict churn.\n\nAs more teams build AI agents on top of knowledge graphs, there is a newer one too: text embeddings tell an agent what things say, graph embeddings tell it how things connect, and retrieval that uses both can find related entities that text alone would miss.\n\nPreviously, creating embeddings was a job for data scientists. Just to get started, you would first have to climb a hill of concepts: *which model fits my graph, which configuration fits my use case, what does this parameter even do?* Plenty of teams have made that climb, trying out models and tuning configuration until the embeddings looked right. It works, but it is a lot to ask before you see a first result.\n\nCompare that with text embeddings. You make one call, get vectors back in a few lines of code, and never need to know what happens under the hood. That bar has been set, and we think graphs deserve the same treatment.\n\n## One line, nothing to configure\n\nToday, we are excited to release, in preview, a new Embeddings API in [the GDS Python client](https://neo4j.com/docs/graph-data-science-client/current/) (version 2.2 or later), built for [Aura Graph Analytics](https://neo4j.com/docs/aura/graph-analytics/aga/):\n\n```\ngds.embedding.create(G)\n```\n\nThat is the whole call.\n\n`G` is your graph, loaded into a session of Aura Graph Analytics, the on-demand environment where GDS runs in Aura, and `create` gives every node in it an embedding. Under the hood, it runs [FastRP](https://neo4j.com/docs/graph-data-science/current/machine-learning/node-embeddings/fastrp/), a fast and highly scalable algorithm, with defaults we chose so you don’t have to, and in most cases they work well. That means you can start without knowing how the algorithm works or how to tune it, and spend your time on what the embeddings are for, not on how to produce them.\n\nWhen you do want the dials, they are there. You can set the embedding size and other FastRP settings, name the property the embeddings are stored in, embed only some node labels or relationship types, and fix a `random_seed` to get reproducible results.\n\n## What happens to your graph\n\nEmbeddings are added to your in-memory graph as a new node property, called `embedding` unless you choose another name, and nothing is written to your database. From there, the vectors are yours: stream them into pandas, hand them to another algorithm in the same session (kNN to find similar nodes, k-means to cluster them), or, if your session is attached to a database, write them back to it. \n\nHere it is in context, starting with the graph itself (accounts and the transfers between them):\n\n```\nG, result = gds.graph.project.native(\"transfers\", [\"Account\"], [\"TRANSFERRED_TO\"])\ngds.embedding.create(G)\n```\n\nAnd here is the same call with a few of the dials turned: an embedding size of 256, a separate property name (since the default `embedding` already exists now on this graph), and a fixed seed for reproducible results:\n\n```\ngds.embedding.create(\n    G,\n    embedding_dimension=256, \n    mutate_property=\"embedding_256\", # a new name since \"embedding\" already exists on G\n    random_seed=42,\n)\n```\n\n`create` fails if the graph already has a property with the same name, so existing embeddings are never overwritten by accident. While you are experimenting, give each set of embeddings its own property name, as in the example above, so you can compare them. In production, in scheduled pipelines, or in notebook cells you want to re-run, drop the property first. With `fail_if_missing=False`, that step is safe: if the property doesn’t exist yet, the line is simply ignored.\n\n```\ngds.graph.node_properties.drop(G, [\"embedding\"], fail_if_missing=False)\ngds.embedding.create(G)\n```\n\n## When the default isn’t enough\n\nOf course, a general-purpose default only goes so far. It captures where each node sits in the overall shape of the graph, and that is all it looks at: whatever is stored on your nodes plays no part. If your accounts contain properties that matter, or your analysts have already classified some of them, you will want embeddings shaped by those properties.\n\nThat is what `gds.embedding.train` is for. It trains a [GraphSAGE](https://neo4j.com/docs/graph-data-science/current/machine-learning/node-embeddings/graph-sage/) model that learns from node properties and from the classes you already know. Once you have a model, pass its name to `create` and you are back to a single call.\n\nIn this example, every account also carries a numeric `risk_class` and a `features` vector, so the projection brings them along:\n\n```\nG, result = gds.graph.project.native(\n    \"labeled-transfers\",\n    [\"Account\"],\n    [\"TRANSFERRED_TO\"],\n    node_properties=[\"risk_class\", \"features\"],\n)\n```\n\nWith those properties in the graph, training takes one call. You point it at the property that holds the classes you already know (`target_label` and `target_property`), the properties the model should learn from (` feature_properties`), and the name to save the model under:\n\n```\ngds.embedding.train(\n    G,\n    model_name=\"account-risk-encoder\",\n    target_label=\"Account\",\n    target_property=\"risk_class\",\n    feature_properties=[\"features\"],\n)\n```\n\nBehind the scenes, a small classifier trained on your known classes teaches the encoder which patterns matter. If the defaults aren’t enough, you can tune both the encoder and the classifier, along with the number of epochs and the batch size.\n\nWhat you keep is the encoder. Pass its name to `create`, and every node gets an embedding shaped by your classes and properties:\n\n```\ngds.embedding.create(\n    G,\n    graph_encoder=\"account-risk-encoder\",\n    mutate_property=\"embedding_tuned\",\n    feature_properties=[\"features\"],\n)\n```\n\nOne word of caution when you evaluate the results: the model has already seen your training examples, so judge it on nodes it did not train on.\n\nA model trained this way is a regular Aura Graph Analytics model, like any other you would train in a session. You can for example store it using `gds.model.store` to keep it in your project’s [model catalog](https://neo4j.com/docs/graph-data-science/current/aura-graph-analytics/machine-learning/), so a later session can use it by name.\n\n## Try it today\n\nAura Graph Analytics is available on the AuraDB Free tier, so you can see this in action without paying anything. And your data does not have to live in Neo4j. Load nodes and relationships from a data warehouse, Databricks, or a CSV file into pandas DataFrames, and [`gds.graph.construct`](https://neo4j.com/docs/graph-data-science-client/current/tutorials/load-data-via-graph-construction/) turns them into a graph in a standalone session. \n\n[The Embeddings API documentation](https://neo4j.com/docs/graph-data-science-client/current/embeddings-api/) has the full parameter reference and a quickstart that runs on Cora, a small citation graph that ships with our GDS Python client, so you can try it before loading anything of your own.\n\nBoth endpoints are in **preview**, which means they may change as we learn from how you use them. The Embeddings API is available only in Aura Graph Analytics, with GDS Python client 2.2 or later.\n\n## What’s next\n\nThis is a first step. We plan to keep adding to the API, with more capabilities for generating embeddings and for putting them to work once you have them, and to bring it to our Cypher API too, if Python isn’t your cup of tea.\n\nBecause this is a preview, your feedback shapes what comes next: tell us which graphs you embedded, what worked, and what you wished it did. Reach out to us on [the Neo4j Community Forum](https://community.neo4j.com/) or at [\\[email protected\\]](https://neo4j.com/cdn-cgi/l/email-protection).", "url": "https://wpnews.pro/news/graph-embeddings-one-line-of-code-away", "canonical_source": "https://neo4j.com/blog/aura-graph-analytics/graph-embeddings-one-line-of-code-away/", "published_at": "2026-10-16 13:44:01+00:00", "updated_at": "2026-10-16 17:53:37.103088+00:00", "lang": "en", "topics": ["artificial-intelligence", "machine-learning", "ai-agents", "developer-tools", "ai-infrastructure"], "entities": ["Neo4j", "Neo4j Graph Data Science", "Aura Graph Analytics", "GDS Python client", "FastRP"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/graph-embeddings-one-line-of-code-away", "markdown": "https://wpnews.pro/news/graph-embeddings-one-line-of-code-away.md", "text": "https://wpnews.pro/news/graph-embeddings-one-line-of-code-away.txt", "jsonld": "https://wpnews.pro/news/graph-embeddings-one-line-of-code-away.jsonld"}}