graphspot
Graph anomaly detection for people who have to score things they have never seen before.
- Inductive by contract. Every detector's
decision_functionscores nodes absent at fit time. NeverNotImplementedError. - Installs without torch. The core is numpy/scipy/sklearn/pandas/xgboost. Deep detectors
live behind
pip install graphspot[deep]. - Honest baselines. Every evaluation can include a no-graph tabular baseline, and graphspot warns loudly when the graph model fails to beat it.
Status: pre-release, under active development. The v0 detector set is
NeighborAggregation (transform), XGBGraph, RFGraph, FlatBaseline, with
FlatUnsupervised, OddBall, Fraudar and BWGNN (behind [deep]) on the way.
import graphspot
from graphspot.detectors import XGBGraph, FlatBaseline
from graphspot.datasets import load_yelpchi
g = load_yelpchi()
det = XGBGraph(random_state=0).fit(g, y=g.node_labels)
flat = FlatBaseline(random_state=0).fit(g, y=g.node_labels)
print(graphspot.evaluate(
g.node_labels,
det.decision_scores_,
baseline_scores=flat.decision_scores_,
))
det.explain(k=5) # e.g. [("2hop_mean(f21)", 0.14), ("1hop_max(f3)", 0.11), ...]
list_detectors() reports what is usable in your environment, and any PyOD detector
runs through graphspot's graphs and benchmarks in one line:
import graphspot
graphspot.list_detectors()
from pyod.models.ecod import ECOD
det = graphspot.compat.from_pyod(ECOD()).fit(g) # ECOD over neighbor-aggregated features
Works directly on transaction dataframes:
g = graphspot.Graph.from_pandas(
tx, source="buyer_id", target="seller_id",
edge_features=["amount"], time="ts",
node_features=accounts.set_index("account_id"),
)
Benchmarks
Every number regenerates from one command: graphspot bench --quick. AUPRC x100,
mean over three seeded trials, on the four auto-download datasets, out-of-the-box
defaults, no torch installed. Tolokers and Questions use the split masks their
upstream ships; the flat baseline is the same XGBoost on raw features with no graph.
dataset XGBGraph RFGraph FlatBaseline
----------------------------------------------------
yelpchi 89.32±0.42* 76.76±0.41 83.45±0.51
amazon 93.75±0.57* 89.70±1.00 90.25±1.22
tolokers 57.34±1.34 58.18±1.35* 38.61±0.70
questions 22.05±1.30* 16.09±1.49 16.77±1.50
Read the losses too: on YelpChi and Amazon the plain random forest does not beat the no-graph baseline. Publishing where the graph does not help is the point.
macOS notes: xgboost needs Homebrew's libomp (brew install libomp). And torch
(the [deep] extra) cannot share a process with xgboost on macOS: each bundles its
own OpenMP runtime and the mix segfaults or deadlocks. graphspot guards this with a
clear error instead of a crash; run deep and tree detectors in separate processes
there. Linux is unaffected.
The acceptance test
Strict-inductive Elliptic, one command, on a laptop, no torch:
uv run python scripts/acceptance_elliptic.py fits on time steps 1-34 and scores
steps 35-49 as a disjoint graph the model has never seen. 203,769 nodes; fit 10.1s,
score 0.8s, peak rss 3.05GB. PyOD's graph detectors raise NotImplementedError on
decision_function; PyGOD's flagship OOMs on this graph on a 12 GB GPU.
Two honest findings the per-step table makes visible. The dark-market shutdown at step 43 collapses every model (AUPRC in the 90s drops to single digits), which is why the script refuses to print a single aggregate number. And on this dataset the graph model does not beat the flat baseline (mean per-step AUPRC 55.3 vs 56.4): Elliptic's feature matrix already contains 72 neighborhood-aggregate columns computed by the dataset authors, so the flat model is quietly graph-informed. The loud baseline exists precisely to surface results like this.
Support
- Versioning: pre-1.0, minor releases may change APIs; anything removed gets a
deprecation release first. Fitted-attribute names (
decision_scores_,labels_,threshold_) are stable and PyOD-compatible. - Scope: node and edge level anomaly detection on static graphs. Graph-level detection and streaming are out of scope for now.
- Every README number regenerates from one command (
scripts/kill_test.py,graphspot bench --quick), and a monthly CI job re-runs them. - Issues and PRs are welcome; small reproducible bug reports get priority.
License: BSD-3-Clause.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file graphspot-0.1.0.tar.gz.
File metadata
- Download URL: graphspot-0.1.0.tar.gz
- Upload date:
- Size: 215.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70a1cdfc503cc05eafe0d93cc5c027dc2883a905fe49a2d50979972080c9f933
|
|
| MD5 |
a7598a33629187fea0853dbb8a9d5ee8
|
|
| BLAKE2b-256 |
55af6ae1efa0390450bc980b186c6b0f1a6bcbf75c7008fd88bd3ae495597d0c
|
Provenance
The following attestation bundles were made for graphspot-0.1.0.tar.gz:
Publisher:
release.yml on JayeshSuryavanshi/graphspot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphspot-0.1.0.tar.gz -
Subject digest:
70a1cdfc503cc05eafe0d93cc5c027dc2883a905fe49a2d50979972080c9f933 - Sigstore transparency entry: 2478274624
- Sigstore integration time:
-
Permalink:
JayeshSuryavanshi/graphspot@fb5f9f8d856fd9c488fb79322f78fe6b45115801 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/JayeshSuryavanshi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb5f9f8d856fd9c488fb79322f78fe6b45115801 -
Trigger Event:
push
-
Statement type:
File details
Details for the file graphspot-0.1.0-py3-none-any.whl.
File metadata
- Download URL: graphspot-0.1.0-py3-none-any.whl
- Upload date:
- Size: 34.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88629e5a11545f082287943104a7edb0bac77f601399f32810ad45b6168e2068
|
|
| MD5 |
259dedba0b8e6655ecc49dbd08977ce9
|
|
| BLAKE2b-256 |
3e6141851c1b46aebed67b0e601cb4c7a14127cc0519984a137bc89c05fd5511
|
Provenance
The following attestation bundles were made for graphspot-0.1.0-py3-none-any.whl:
Publisher:
release.yml on JayeshSuryavanshi/graphspot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphspot-0.1.0-py3-none-any.whl -
Subject digest:
88629e5a11545f082287943104a7edb0bac77f601399f32810ad45b6168e2068 - Sigstore transparency entry: 2478274693
- Sigstore integration time:
-
Permalink:
JayeshSuryavanshi/graphspot@fb5f9f8d856fd9c488fb79322f78fe6b45115801 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/JayeshSuryavanshi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb5f9f8d856fd9c488fb79322f78fe6b45115801 -
Trigger Event:
push
-
Statement type: