neo4j-gds-skill について
組み込み GDS プラグインを使う Neo4j Graph Data Science 向けのスキルです。Python クライアントまたは Cypher によるグラフ投影とアルゴリズム実行、メモリ見積もり、結果の書き戻しを扱います。
主な機能
- 01インメモリーグラフの投影と管理
- 02中心性・コミュニティアルゴリズムの実行
- 03類似度・経路・埋め込みアルゴリズムの実行
- 04stream・stats・mutate・write モード
- 05投影とアルゴリズムのメモリ見積もり
- 06Python クライアントまたは Cypher による操作
活用シーン
- 01ネットワークの重要ノードやコミュニティを特定
- 02ノード類似度や経路を分析
- 03ベクトルインデックス向けのノード埋め込みを生成
- 04大規模なグラフ処理の前にメモリを見積もる
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ neo4j-contrib/ neo4j-skills --skill neo4j-gds-skillインストール後、Claude Code で/neo4j-gds-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/algorithms.mdgraph-projection.md詳細
使用する場合
- Python クライアント(
graphdatascience)を通じて、組み込み GDS プラグインに対して GDS アルゴリズムを実行する場合 CALL gds.*Cypher プロシージャを通じて GDS アルゴリズムを実行する場合- Aura Pro、セルフマネージドの Neo4j、ローカルの Neo4j、または GDS プラグインをインストール済みのオフライン DBMS を使用する場合
- 名前付きのインメモリグラフをプロジェクションし、中心性/コミュニティ/類似性/パス/埋め込みアルゴリズムを実行する場合
mutateモードでアルゴリズムを連鎖させ、FastRP → KNN パイプラインを構築する場合- Neo4j ベクトルインデックス/構造的類似性検索用にノード埋め込みを書き込む場合
- 大規模なグラフ操作の前にメモリを見積もる場合
使用しない場合
- Aura Graph Analytics Sessions / AGA /
GdsSessions/AuraGraphDataScience→neo4j-aura-graph-analytics-skill { memory: ... }または{ sessionId: ... }を使う AuraDB Cypher API →neo4j-aura-graph-analytics-skill- Cypher クエリの作成 →
neo4j-cypher-skill - ドライバー/接続の設定 →
neo4j-driver-python-skill - GraphRAG による検索 →
neo4j-graphrag-skill - 書き込み済みの埋め込みに対するベクトルインデックスの作成/クエリ →
neo4j-vector-index-skill
| コンテキスト | 使用するもの |
|---|---|
| GDS プラグインを備えた Aura Pro | このスキル |
| GDS プラグインを備えたセルフマネージド/ローカル/オフラインの Neo4j | このスキル |
| AuraDB のサーバーレス分析セッション | neo4j-aura-graph-analytics-skill |
| AGA セッションに接続されたセルフマネージド Neo4j | neo4j-aura-graph-analytics-skill |
| Neo4j 以外のデータソース | neo4j-aura-graph-analytics-skill |
事前確認
組み込み GDS プラグインでのみ使用してください。
from graphdatascience import GraphDataScience
gds = GraphDataScience("neo4j+s://xxx.databases.neo4j.io", auth=("neo4j", "pw")) # AuraDS; aura_ds auto-derived
gds = GraphDataScience("bolt://localhost:7687", auth=("neo4j", "password"))
print(gds.server_version())
RETURN gds.version() AS gds_version
GDS プラグインが利用できない場合:クライアントは構築時に GdsNotFound を送出し、Cypher は Unknown function 'gds.version' を送出します。AuraDB のサーバーレス分析 → neo4j-aura-graph-analytics-skill。セルフマネージド/ローカルの場合 → GDS プラグインをインストールまたは有効化してください。
pip install "graphdatascience>=2.1" # 2.1 required for GDS 2026.09
pip install "graphdatascience[rust-ext]" # optional: faster serialization
互換性:graphdatascience 2.1 / 2.2 — GDS >= 2.13、かつ < 2.28 / < 2026.10。2.0 — GDS < 2026.9。すべてのバージョン:Python >= 3.10、かつ < 3.15、Neo4j Python driver >= 5.26、かつ < 7.0、pandas 2–3、pyarrow 21–25。GDS サーバーが < 2.13 の場合 → 構築時に DeprecationWarning が発生します。その場合は graphdatascience<2(クライアント 1.22)に固定してください。
クライアント 1.x へのフォールバック(GDS サーバー < 2.13)
| 2.0 | 1.x クライアント |
|---|---|
gds.page_rank、gds.louvain、… — v2 プレフィックスなし | gds.v2.page_rank、gds.v2.louvain、… |
gds.graph.project.native(...) | gds.v2.graph.project(...) |
gds.graph.project.cypher(query) | gds.graph.cypher.project(query, database=...) |
Graph / Model | GraphV2 / ModelV2 |
gds.graph.drop(...) → list[GraphInfo] | gds.v2.graph.drop(...) → 単一の GraphInfo |
Graph.drop(fail_if_missing=) | Graph.drop(failIfMissing=) |
run_cypher(...) — 常に再試行 | run_cypher(..., retryable=...) |
移行ガイド:Neo4j GDS Python クライアント 2.0 への移行
GDS プラグインのリリースはサーバーに対応しています。2026.09.0 には Neo4j 2026.09 が必要です。いずれかをアップグレードする前に、GDS の互換性表を確認してください。
GDS プラグイン 2026.07.0 では CALL gds.userLog() が削除されました。ドライバーの結果サマリー通知または Neo4j のデバッグログからヒントと警告を確認し、CALL gds.listProgress() でタスクの進行状況を追跡してください。
2.0 クライアントのルール:
- プレフィックスのないエンドポイントを使用します。型指定のない 1.x エンドポイントと
gds.v2.*は廃止されています - パラメーターは snake_case です:
page_rank、fast_rp、mutate_property、write_property - 型指定された結果属性を使用します:
result["writeMillis"]ではなくresult.write_millis(streamは引き続き DataFrame を返します) - サーバーのバージョンは
gds.server_version()で取得します。クライアントメソッドgds.version()はありません(Cypher のRETURN gds.version()は引き続き有効です) - プロシージャーの別名:
gds.betweenness≡gds.betweenness_centrality。同様にgds.closeness、gds.degree、gds.eigenvector、gds.harmonic、gds.kcore - パイプライン:
gds.pipeline.node_classification/link_prediction/node_regression— 2.0 で使用できる唯一の API です CALL { … } IN TRANSACTIONSにはgds.run_cypher(query, auto_commit=True)[2.1] を使用します。2.0 のデフォルトの再試行可能トランザクションでは拒否されます。2.0 では Neo4j ドライバーを直接使用してください- カスタムセッション/トランザクション用の基盤となる
neo4j.Driverを返すgds.db_driver()[2.1]。クライアントが作成した場合に限り、gds.close()によって閉じられます QueryModeが使用できる箇所では、mode="READ"/"WRITE"の文字列を使用できます [2.1]- プラグインの API には非同期/ジョブハンドル API はありません。
compute()、*_async、gds.jobsは AGA Sessions 専用です
グラフカタログの操作
ネイティブプロジェクション
CALL gds.graph.project(
'myGraph',
['Person', 'City'],
{ KNOWS: { orientation: 'UNDIRECTED' }, LIVES_IN: {} }
)
YIELD graphName, nodeCount, relationshipCount
G, result = gds.graph.project.native("myGraph", "Person", "KNOWS")
print(result.node_count, result.relationship_count)
G, result = gds.graph.project.native(
"myGraph",
{"Person": {"properties": ["age", "score"]}, "City": {}},
{"KNOWS": {"orientation": "UNDIRECTED"}, "LIVES_IN": {"properties": ["since"]}},
overwrite=True, # drop same-named graph first
)
ネイティブプロジェクション:プラグイン/シンプルな Python クライアントのワークフローのみで使用します。AGA Sessions では neo4j-aura-graph-analytics-skill を使用してください。
1.x へのフォールバック:gds.v2.graph.project(...)。
Cypher プロジェクション(新しい Cypher ワークフロー、フィルター、変換に使用)
G, result = gds.graph.project.cypher(
"""
MATCH (source:Person)-[r:KNOWS]->(target:Person)
WHERE source.active = true
RETURN gds.graph.project($graph_name, source, target,
{ sourceNodeProperties: source { .score }, relationshipType: 'KNOWS' })
""",
graph_name="activeGraph",
)
gds.graph.project.cypher(query) は database= を受け取りません。GraphDataScience(..., database=...) を構築時に設定するか、プロジェクションの前に gds.set_database(...) を呼び出してください。
クエリの末尾には、RETURN gds.graph.project(...) が正確に 1 つ必要です。検証に失敗した場合は、gds.run_cypher(...) を使用してから gds.graph.get("graphName") を呼び出してください。
1.x へのフォールバック:gds.graph.cypher.project(query, database=...)。
AGA Sessions では neo4j-aura-graph-analytics-skill を使用してください。プラグインの Cypher プロジェクションは使用しないでください。
無向プロジェクション
ネイティブプロジェクション:リレーションシップタイプごとに orientation: 'UNDIRECTED' を設定します。
プラグインの Cypher プロジェクション:5 番目の gds.graph.project(...) 設定引数に undirectedRelationshipTypes: ['*'] を設定します。
Leiden は有向グラフと無向グラフの両方で定義されています。コミュニティ構造が本質的に対称な場合は、無向リレーションシップとしてプロジェクションしてください。
確認と削除
G.node_count() # 12_043
G.relationship_count() # 87_211
G.node_properties() # projected + mutated properties by label
G.relationship_properties() # projected + mutated properties by type
G.size_in_bytes()
gds.graph.drop(G) # frees JVM heap; returns list[GraphInfo]
G = gds.graph.get("myGraph") # re-attach to existing projection
gds.graph.list()
メモリーの見積もり — 大規模なプロジェクションやアルゴリズムを実行する前に実行してください
CALL gds.graph.project.estimate(['Person'], 'KNOWS')
YIELD requiredMemory, bytesMin, bytesMax, nodeCount, relationshipCount
est = gds.graph.project.estimate(node_projection=["Person"], relationship_projection=["KNOWS"])
print(est.required_memory)
G, project_result = gds.graph.project.native("myGraph", "Person", "KNOWS")
print(project_result.node_count)
# Algorithm estimation:
est = gds.page_rank.estimate(G, damping_factor=0.85)
print(est.required_memory)
実行モード
| モード | 副作用 | 戻り値 | 使用する場面 |
|---|---|---|---|
stream | なし | ノード/ペアごとに1行 | 結果の確認、上位N件の取得 |
stats | なし | 集計行1行 | 要約/収束の確認 |
mutate | インメモリーグラフのみにノードプロパティ、またはリレーションシップのタイプ/プロパティを追加 | 統計行 | アルゴリズムの連鎖 |
write | Neo4j DBにノードプロパティまたはリレーションシップを永続化 | 統計行 | 最終ステップ — クエリ可能にする |
パターン:streamで確認 → mutateで連鎖 → writeで永続化します。
mutate_propertyはインメモリーグラフに存在していてはいけません。KNNなどのリレーションシップアルゴリズムでは、mutate_relationship_typeも必要です。
writeの後に、以降のGDS呼び出しで書き込んだプロパティを使用するには、再度プロジェクションしてください(インメモリーグラフからはDBへの書き込みが見えません)。
gds.util.asNode() — ストリーム結果の拡充
streamモードではnodeId(GDS内部の整数値)が返されます。gds.util.asNode(nodeId)でDBのノードに変換すると、プロパティにアクセスできます。
// Single property
CALL gds.pageRank.stream('myGraph', {})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score
ORDER BY score DESC LIMIT 10
// Multiple properties — convert once with WITH
CALL gds.pageRank.stream('myGraph', {})
YIELD nodeId, score
WITH gds.util.asNode(nodeId) AS node, score
RETURN node.name AS name, node.born AS born, score
ORDER BY score DESC LIMIT 10
write、mutate、statsモードでは不要です。これらのモードはノードごとのデータを返しません。
コアアルゴリズム
PageRank(中心性)
CALL gds.pageRank.stream('myGraph', { dampingFactor: 0.85, maxIterations: 20 })
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score ORDER BY score DESC LIMIT 10
// score: relative influence — not absolute. Compare within same run only.
// didConverge: true means score stabilized; if false, increase maxIterations.
CALL gds.pageRank.write('myGraph', { writeProperty: 'pagerank', dampingFactor: 0.85 })
YIELD nodePropertiesWritten, ranIterations, didConverge
pr_df = gds.page_rank.stream(G, damping_factor=0.85)
mutate_result = gds.page_rank.mutate(G, mutate_property="pagerank", damping_factor=0.85)
write_result = gds.page_rank.write(G, write_property="pagerank", damping_factor=0.85)
print(write_result.write_millis)
Louvain(コミュニティ検出)
CALL gds.louvain.stream('myGraph', { relationshipWeightProperty: 'weight' })
YIELD nodeId, communityId
CALL gds.louvain.write('myGraph', { writeProperty: 'community' })
YIELD communityCount, modularity
louvain_df = gds.louvain.stream(G)
write_result = gds.louvain.write(G, write_property="community")
print(write_result.community_count)
Leidenは、結びつきの弱いコミュニティを避けるためにLouvainを改良したものです。速度よりコミュニティの品質を重視する場合に使用してください。
統計結果のmodularityの範囲は-0.5~1.0です。[field] 0.3を超える値は意味のあるコミュニティ構造を示すことが多く、0.7を超える値は強い構造を示します。
Leidenは有向グラフと無向グラフの両方に対応しています。コミュニティ構造が自然に対称となる場合は、無向リレーションシップをプロジェクションしてください。
WCC — 弱連結成分
コストの高いアルゴリズムを実行する前に、まずWCCを実行してグラフ構造を把握し、非連結グラフを分割してください。
CALL gds.wcc.stream('myGraph', { minComponentSize: 10 })
YIELD nodeId, componentId
CALL gds.wcc.write('myGraph', { writeProperty: 'componentId' })
YIELD nodePropertiesWritten, componentCount
wcc_df = gds.wcc.stream(G)
write_result = gds.wcc.write(G, write_property="componentId")
print(write_result.node_properties_written)
Betweenness Centrality(媒介中心性)
gds.betweenness.stream(G) # alias of betweenness_centrality; identifies bottleneck/bridge nodes
gds.betweenness.write(G, write_property="betweenness")
Node Similarity(ノード類似度)
共通の隣接ノードからJaccard類似度を計算します。ノードプロパティは不要です。
gds.node_similarity.stream(G, similarity_cutoff=0.1, top_k=10)
gds.node_similarity.write(G, write_relationship_type="SIMILAR", write_property="score",
similarity_cutoff=0.1, top_k=10)
FastRP(ノード埋め込み)
高速でスケーラブルな、本番環境向けのMLパイプラインです。再現性を確保するにはrandomSeedを設定してください。
CALL gds.fastRP.mutate('myGraph', {
embeddingDimension: 256,
iterationWeights: [0.0, 1.0, 1.0],
featureProperties: ['score'],
propertyRatio: 0.5,
normalizationStrength: -0.5,
randomSeed: 42,
mutateProperty: 'embedding'
})
YIELD nodePropertiesWritten
gds.fast_rp.mutate(G, embedding_dimension=256, iteration_weights=[0.0, 1.0, 1.0],
random_seed=42, mutate_property="embedding")
write_result = gds.fast_rp.write(G, embedding_dimension=256, write_property="embedding",
random_seed=42)
print(write_result.write_millis)
構造埋め込みに対してANN検索を行うには、writeの後に、書き込んだプロパティを対象とするNeo4jベクトルインデックスを作成してください。neo4j-vector-index-skillを使用します。
KNN — k近傍法
ノードプロパティ(通常は埋め込み)に基づいて、各ノードに最も類似したk個のノードを特定します。
CALL gds.knn.stream('myGraph', {
nodeProperties: ['embedding'], topK: 10,
sampleRate: 0.5, similarityCutoff: 0.7
})
YIELD node1, node2, similarity
CALL gds.knn.write('myGraph', {
nodeProperties: ['embedding'], topK: 10,
writeRelationshipType: 'SIMILAR', writeProperty: 'score'
})
YIELD relationshipsWritten
knn_df = gds.knn.stream(G, node_properties=["embedding"], top_k=10)
gds.knn.write(G, node_properties=["embedding"], top_k=10,
write_relationship_type="SIMILAR", write_property="score")
FastRP → KNNパイプライン(レコメンデーション)
# 1. Project
G, _ = gds.graph.project.native("myGraph", "Product",
{"BOUGHT_TOGETHER": {"orientation": "UNDIRECTED"}})
# 2. Estimate memory
print(gds.fast_rp.estimate(G, embedding_dimension=128).required_memory)
# 3. Embed
gds.fast_rp.mutate(G, embedding_dimension=128, random_seed=42, mutate_property="emb")
# 4. Similarity
gds.knn.write(G, node_properties=["emb"], top_k=10,
write_relationship_type="SIMILAR", write_property="score")
# 5. Cleanup
gds.graph.drop(G)
アルゴリズムの選択
| 目標 | アルゴリズム |
|---|---|
| ネットワークリンクを介した影響力 | PageRank / ArticleRank |
| ボトルネック/橋渡しとなるノード | Betweenness Centrality |
| 直接のつながり | Degree Centrality |
| コミュニティ(汎用、高速) | Louvain |
| コミュニティ(高品質) | Leiden |
| グラフが連結しているか | WCC(最初に実行) |
| 埋め込みに基づく類似度 | KNN |
| 隣接ノードに基づく類似度 | Node Similarity |
| 最短経路(正の重み) | Dijkstra / A* |
| k個の代替経路 | Yen's |
| 高速でスケーラブルな埋め込み | FastRP |
| 特徴量が豊富なノード | GraphSAGE(クライアント:gds.graph_sage、Cypher:gds.beta.graphSage) |
アルゴリズムの全一覧 → references/algorithms.md
よくあるエラー
| エラー | 原因 | 対処方法 |
|---|---|---|
Unknown function 'gds.version' | 埋め込み GDS プラグインを利用できません | AGA → neo4j-aura-graph-analytics-skill、セルフマネージド/ローカル → プラグインをインストール |
クライアントの構築時に GdsNotFound | 対象の DB に GDS プラグインがインストールされていません | GDS プラグインをインストール/有効化します。AuraDS エンドポイントは GDS がある場合に限り使用できます |
AttributeError: ... no attribute 'version' | クライアント 2.0 には gds.version() が存在しません | gds.server_version() を使用します |
クライアントの構築時に DeprecationWarning | GDS サーバーのバージョンが 2.13 未満です | GDS サーバーをアップグレードするか、graphdatascience<2 に固定して 1.x の対応表を使用します |
Insufficient heap memory / OOM | グラフが利用可能な JVM ヒープに対して大きすぎます | gds.graph.project.estimate を実行します。server.memory.heap.max_size を増やします |
Procedure not found: gds.leiden | GDS のバージョンが古いか、互換性がありません | CALL gds.list() で利用可能なプロシージャを確認します。GDS をアップグレードするか、Louvain を使用します |
mutate の後に Node property 'X' not found | プロパティがプロジェクションされていないか、グラフ名が間違っています | G.node_properties() にプロパティが含まれていることを確認します。mutate_property のスペルを確認します |
Graph 'myGraph' already exists | 失敗した実行によるプロジェクションが残っています | overwrite=True、CALL gds.graph.drop('myGraph')、または gds.graph.drop(G) を使用します |
mutate_property already exists | 同じプロジェクションでアルゴリズムを再実行しています | グラフを削除して再プロジェクションするか、別の mutate_property 名を使用します |
No algorithm results | ソース/ターゲットノードがプロジェクションに含まれていません | ノードラベル/リレーションシップタイプがプロジェクションと一致することを確認します。G.node_count() を確認します |
gds.graph.drop(...) の後に AttributeError: 'list' object ... | 2.0 は list[GraphInfo] を返します | 結果をインデックスで参照します。1.x クライアントは単一の GraphInfo を返します |
run_cypher からの A query with 'CALL { ... } IN TRANSACTIONS' can only be executed in an implicit transaction | 2.0 はすべてのクエリを再試行可能なマネージドトランザクションで実行します | graphdatascience>=2.1 を使用し、run_cypher(query, auto_commit=True) を指定します |
ワークフロー全体
GraphDataScience(...)でgdsを作成します。- プラグインを確認します:
gds.server_version()またはRETURN gds.version()。 - メモリを見積もります:
gds.graph.project.estimate(...)とアルゴリズムの.estimate(...)。 gds.graph.project.native(...)またはgds.graph.project.cypher(query)で名前付きグラフをプロジェクションします。- まず
gds.*.streamを実行し、その後mutateに切り替えます。納得できた場合にのみwriteを使用します。 gds.graph.drop(G)でグラフを削除します。- GDS サーバーが 2.13 未満の場合 → 上記の対応表を使ってクライアントを 1.22 にします。
組み込みのテストデータセット:gds.graph.datasets.load_cora()、gds.graph.datasets.load_karate_club()、gds.graph.datasets.load_imdb()
MCP ツールの対応付け
| 操作 | MCP ツール |
|---|---|
RETURN gds.version() | read-cypher |
gds.pageRank.stream(...) | read-cypher |
gds.pageRank.write(...) | write-cypher |
gds.graph.drop(...) | write-cypher |
| 利用可能なプロシージャの一覧表示 | read-cypher → CALL gds.list() |
write-cypher を実行する前に、正確な Cypher、影響を受けるノード/リレーションシップの予想数を提示し、確認を求めてください。アルゴリズムの write モードでは、利用可能な場合、事前に estimate を実行するか stats を実行してください。
参考資料
- references/algorithms.md — アルゴリズムの全カタログ:すべてのプロシージャ、パラメーター、階層、Cypher と Python の例
- references/graph-projection.md — プロジェクションの詳細:フィルタリング、異種グラフ、リレーションシップの向き、プロパティの型
- GDS マニュアル
- Python クライアントのドキュメント
チェックリスト
-
gds.server_version()またはRETURN gds.version()で埋め込み GDS プラグインを確認済み - 大規模な処理の前に、グラフ/アルゴリズムのメモリ使用量を見積もり済み
- Python の例では 2.0 のエンドポイント(
v2プレフィックスなし)、snake_case のパラメーター、型付きの結果属性を使用 - クライアント 1.x は、対応表に従い GDS サーバーが 2.13 未満の場合にのみ使用
- プロジェクションではネイティブまたはプラグインの Cypher プロジェクションを使用し、
gds.graph.project.remote(...)は使用しない - 使用後に名前付きグラフを削除(
gds.graph.drop(G)。1.x:gds.v2.graph.drop(G)) - 実行モードを選択:
stream(確認)→mutate(連鎖)→write(永続化) -
write_property/mutate_propertyが既存のプロパティと衝突しないことを確認 - 既存のグラフ名を再プロジェクションする場合は
overwrite=Trueを設定 - 再現可能な埋め込みのために
randomSeedを設定 - 非連結の可能性があるグラフでは、最初に WCC を実行